webrtcvideoengine2.cc revision 43edf0ffb91a50e2efa01c7befe4d188a7e30ea2
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 2467fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic std::string RtpExtensionsToString( 2477fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 2487fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::stringstream out; 2497fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '{'; 2507fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 2517fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; 2527fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (i != extensions.size() - 1) { 2537fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << ", "; 2547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2557fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '}'; 2577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return out.str(); 2587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 2597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 26064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shiehinline const webrtc::RtpExtension* FindHeaderExtension( 26164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const std::vector<webrtc::RtpExtension>& extensions, 26264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const std::string& name) { 26364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh for (const auto& kv : extensions) { 26464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (kv.name == name) { 26564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return &kv; 26664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 26764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 26864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return NULL; 26964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh} 27064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 27182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org// Merges two fec configs and logs an error if a conflict arises 272e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin// such that merging in different order would trigger a different output. 27382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.orgstatic void MergeFecConfig(const webrtc::FecConfig& other, 27482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::FecConfig* output) { 27582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.ulpfec_payload_type != -1) { 27682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->ulpfec_payload_type != -1 && 27782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type != other.ulpfec_payload_type) { 27882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: " 27982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->ulpfec_payload_type << " and " 28082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.ulpfec_payload_type; 28182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 28282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type = other.ulpfec_payload_type; 28382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 28482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.red_payload_type != -1) { 28582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->red_payload_type != -1 && 28682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type != other.red_payload_type) { 28782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging red_payload_type configs: " 28882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->red_payload_type << " and " 28982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.red_payload_type; 29082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 29182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type = other.red_payload_type; 29282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 293e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (other.red_rtx_payload_type != -1) { 294e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (output->red_rtx_payload_type != -1 && 295e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin output->red_rtx_payload_type != other.red_rtx_payload_type) { 296e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin LOG(LS_WARNING) << "Conflict merging red_rtx_payload_type configs: " 297e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin << output->red_rtx_payload_type << " and " 298e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin << other.red_rtx_payload_type; 299e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 300e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin output->red_rtx_payload_type = other.red_rtx_payload_type; 301e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 30282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org} 303fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric 304fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric// Returns true if the given codec is disallowed from doing simulcast. 305fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahricbool IsCodecBlacklistedForSimulcast(const std::string& codec_name) { 3063ed348707e93980fd74246f7a1dfab011f841087asapersson return CodecNamesEq(codec_name, kH264CodecName) || 3073ed348707e93980fd74246f7a1dfab011f841087asapersson CodecNamesEq(codec_name, kVp9CodecName); 308fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric} 309fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric 3101c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson// The selected thresholds for QVGA and VGA corresponded to a QP around 10. 3111c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson// The change in QP declined above the selected bitrates. 3121c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Perssonstatic int GetMaxDefaultVideoBitrateKbps(int width, int height) { 3131c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson if (width * height <= 320 * 240) { 3141c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson return 600; 3151c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson } else if (width * height <= 640 * 480) { 3161c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson return 1700; 3171c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson } else if (width * height <= 960 * 540) { 3181c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson return 2000; 3191c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson } else { 3201c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson return 2500; 3211c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson } 3221c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson} 3237fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} // namespace 324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 32581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// Constants defined in talk/media/webrtc/constants.h 32681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// TODO(pbos): Move these to a separate constants.cc file. 32781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kMinVideoBitrate = 30; 32881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kStartVideoBitrate = 300; 32981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 33081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kVideoMtu = 1200; 33181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kVideoRtpBufferSize = 65536; 33281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 333b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 334b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// duration hasn't been implemented. 335b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 336b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 337933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.orgstatic const int kDefaultQpMax = 56; 338933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org 339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 34181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmstd::vector<VideoCodec> DefaultVideoCodecList() { 34281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström std::vector<VideoCodec> codecs; 3433ed348707e93980fd74246f7a1dfab011f841087asapersson codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, 3443ed348707e93980fd74246f7a1dfab011f841087asapersson kVp8CodecName)); 34581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (CodecIsInternallySupported(kVp9CodecName)) { 34681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp9PlType, 34781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström kVp9CodecName)); 34881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // TODO(andresp): Add rtx codec for vp9 and verify it works. 34981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 35071f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin if (CodecIsInternallySupported(kH264CodecName)) { 35171f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultH264PlType, 35271f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin kH264CodecName)); 35371f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } 35481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back( 35581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström VideoCodec::CreateRtxCodec(kDefaultRtxVp8PlType, kDefaultVp8PlType)); 35681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(VideoCodec(kDefaultRedPlType, kRedCodecName)); 35781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName)); 35881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return codecs; 35981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 36081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& requested_codec, 363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* matching_codec) { 364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *matching_codec = codecs[i]; 367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 3733c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic bool ValidateRtpHeaderExtensionIds( 3743c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 3753c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::set<int> extensions_used; 3763c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 37723914fe756903353eae13fffc868d2c84f51f06fPeter Boström if (extensions[i].id <= 0 || extensions[i].id >= 15 || 3783c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org !extensions_used.insert(extensions[i].id).second) { 3793c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; 3803c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 3813c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 3823c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 3833c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return true; 3843c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 3853c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 386c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.orgstatic bool CompareRtpHeaderExtensionIds( 387c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const webrtc::RtpExtension& extension1, 388c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const webrtc::RtpExtension& extension2) { 389c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // Sorting on ID is sufficient, more than one extension per ID is unsupported. 390c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return extension1.id > extension2.id; 391c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org} 392c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 3933c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic std::vector<webrtc::RtpExtension> FilterRtpExtensions( 3943c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 3953c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::vector<webrtc::RtpExtension> webrtc_extensions; 3963c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 3973c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org // Unsupported extensions will be ignored. 39823fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg if (webrtc::RtpExtension::IsSupportedForVideo(extensions[i].uri)) { 3993c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org webrtc_extensions.push_back(webrtc::RtpExtension( 4003c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org extensions[i].uri, extensions[i].id)); 4013c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } else { 4023c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; 4033c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 4043c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 405c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 406c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // Sort filtered headers to make sure that they can later be compared 407c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // regardless of in which order they were entered. 408c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::sort(webrtc_extensions.begin(), webrtc_extensions.end(), 409c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org CompareRtpHeaderExtensionIds); 4103c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return webrtc_extensions; 4113c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 4123c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 413c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.orgstatic bool RtpExtensionsHaveChanged( 414c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const std::vector<webrtc::RtpExtension>& before, 415c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const std::vector<webrtc::RtpExtension>& after) { 416c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before.size() != after.size()) 417c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 418c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org for (size_t i = 0; i < before.size(); ++i) { 419c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before[i].id != after[i].id) 420c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 421c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before[i].name != after[i].name) 422c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 423c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org } 424c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return false; 425c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org} 426c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 427a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.orgstd::vector<webrtc::VideoStream> 428f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateSimulcastVideoStreams( 429d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 430d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 431dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 432d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 433a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org int max_qp = kDefaultQpMax; 434a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 435a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 436a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org return GetSimulcastConfig( 437be16f79818d7c21b747189b3e86d8d98add3e6b1pbos num_streams, codec.width, codec.height, max_bitrate_bps, max_qp, 438a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate); 439a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org} 440a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 441f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgstd::vector<webrtc::VideoStream> 442f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoStreams( 443a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoCodec& codec, 444a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoOptions& options, 445dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 446a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org size_t num_streams) { 447dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int codec_max_bitrate_kbps; 448dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (codec.GetParam(kCodecParamMaxBitrate, &codec_max_bitrate_kbps)) { 449dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps = codec_max_bitrate_kbps * 1000; 450dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström } 451dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (num_streams != 1) { 452dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return CreateSimulcastVideoStreams(codec, options, max_bitrate_bps, 453dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström num_streams); 454dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström } 455dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 456dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // For unset max bitrates set default bitrate for non-simulcast. 4571c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson if (max_bitrate_bps <= 0) { 4581c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson max_bitrate_bps = 4591c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson GetMaxDefaultVideoBitrateKbps(codec.width, codec.height) * 1000; 4601c7d48d431e098ba42fa6bd9f1cfe69a703edee5Ă…sa Persson } 461a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 462d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 463d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 464d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 465d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 46682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate; 467d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 468008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org stream.min_bitrate_bps = kMinVideoBitrate * 1000; 469dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate_bps; 470d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 471933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org int max_qp = kDefaultQpMax; 472d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 473d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 474d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 475d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 476d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 477d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 478b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 479f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgvoid* WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( 4806f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 481143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng const VideoOptions& options, 482143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng bool is_screencast) { 4832feafdb742226f57588d9c95bc25b2202166688fPeter Boström // No automatic resizing when using simulcast or screencast. 4842feafdb742226f57588d9c95bc25b2202166688fPeter Boström bool automatic_resize = 4852feafdb742226f57588d9c95bc25b2202166688fPeter Boström !is_screencast && parameters_.config.rtp.ssrcs.size() == 1; 486143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng bool frame_dropping = !is_screencast; 487143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng bool denoising; 4884cba4eba596706f2238d14f96f4e181f47e5034cpbos bool codec_default_denoising = false; 489143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng if (is_screencast) { 490143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng denoising = false; 491143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng } else { 4924cba4eba596706f2238d14f96f4e181f47e5034cpbos // Use codec default if video_noise_reduction is unset. 493102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg codec_default_denoising = !options.video_noise_reduction; 494102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg denoising = options.video_noise_reduction.value_or(false); 495143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng } 496143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng 497e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(codec.name, kVp8CodecName)) { 498f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp8 = webrtc::VideoEncoder::GetDefaultVp8Settings(); 499143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp8.automaticResizeOn = automatic_resize; 5004cba4eba596706f2238d14f96f4e181f47e5034cpbos // VP8 denoising is enabled by default. 5014cba4eba596706f2238d14f96f4e181f47e5034cpbos encoder_settings_.vp8.denoisingOn = 5024cba4eba596706f2238d14f96f4e181f47e5034cpbos codec_default_denoising ? true : denoising; 503143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp8.frameDroppingOn = frame_dropping; 504f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp8; 5056f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 506e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(codec.name, kVp9CodecName)) { 507f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp9 = webrtc::VideoEncoder::GetDefaultVp9Settings(); 5084cba4eba596706f2238d14f96f4e181f47e5034cpbos // VP9 denoising is disabled by default. 5094cba4eba596706f2238d14f96f4e181f47e5034cpbos encoder_settings_.vp9.denoisingOn = 5104cba4eba596706f2238d14f96f4e181f47e5034cpbos codec_default_denoising ? false : denoising; 511143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp9.frameDroppingOn = frame_dropping; 512f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp9; 513188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } 5146f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 5156f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 5166f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 517afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgDefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler() 518afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org : default_recv_ssrc_(0), default_renderer_(NULL) {} 519afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 520afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgUnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc( 521a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org WebRtcVideoChannel2* channel, 522afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org uint32_t ssrc) { 523afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 524afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 525afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDropPacket; 526afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 527afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 528afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org StreamParams sp; 529afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org sp.ssrcs.push_back(ssrc); 530afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 531a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org if (!channel->AddRecvStream(sp, true)) { 532afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Could not create default receive stream."; 533afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 534afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 535afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(ssrc, default_renderer_); 536afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_recv_ssrc_ = ssrc; 537afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDeliverPacket; 538afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 539afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 540afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgVideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { 541afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return default_renderer_; 542afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 543afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 544afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgvoid DefaultUnsignalledSsrcHandler::SetDefaultRenderer( 545afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 546afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoRenderer* renderer) { 547afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_renderer_ = renderer; 548afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { 549afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(default_recv_ssrc_, default_renderer_); 550afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 551afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 552afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 553709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik SolenbergWebRtcVideoEngine2::WebRtcVideoEngine2() 554709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg : initialized_(false), 5550a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_(NULL), 5560a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_(NULL) { 557b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; 5587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 559587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 560587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 561587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpTimestampOffsetHeaderExtensionDefaultId)); 562587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 563587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 564587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 56564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh rtp_header_extensions_.push_back( 56664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh RtpHeaderExtension(kRtpVideoRotationHeaderExtension, 56764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh kRtpVideoRotationHeaderExtensionDefaultId)); 568c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan if (webrtc::field_trial::FindFullName("WebRTC-SendSideBwe") == "Enabled") { 569c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan rtp_header_extensions_.push_back(RtpHeaderExtension( 570c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan kRtpTransportSequenceNumberHeaderExtension, 571c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan kRtpTransportSequenceNumberHeaderExtensionDefaultId)); 572c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan } 573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 5799a416bd14ee225d8f1a1ada627a1dd7daf275032Fredrik Solenbergvoid WebRtcVideoEngine2::Init() { 580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 581b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 582b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 583b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 584b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 585b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoEncoderConfig& config) { 5868fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org const VideoCodec& codec = config.max_codec; 587957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org bool supports_codec = false; 588957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org for (size_t i = 0; i < video_codecs_.size(); ++i) { 589e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(video_codecs_[i].name, codec.name)) { 5902a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].width = codec.width; 5912a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].height = codec.height; 5922a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].framerate = codec.framerate; 593957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org supports_codec = true; 594957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org break; 595957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org } 596957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org } 597957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org 598957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org if (!supports_codec) { 599957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported: " 6008fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org << codec.ToString(); 6018fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return false; 6028fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 6038fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 605b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 606b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 608709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg webrtc::Call* call, 609709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg const VideoOptions& options) { 61091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(initialized_); 611709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg LOG(LS_INFO) << "CreateChannel. Options: " << options.ToString(); 612b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg return new WebRtcVideoChannel2(call, options, video_codecs_, 613709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg external_encoder_factory_, external_decoder_factory_); 614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 618b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return rtp_header_extensions_; 623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 6250a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalDecoderFactory( 6260a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoDecoderFactory* decoder_factory) { 62791d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(!initialized_); 6280a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_ = decoder_factory; 6290a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 6300a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 6310a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalEncoderFactory( 6320a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoEncoderFactory* encoder_factory) { 63391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(!initialized_); 634f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (external_encoder_factory_ == encoder_factory) 635f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org return; 636f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 637f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // No matter what happens we shouldn't hold on to a stale 638f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // WebRtcSimulcastEncoderFactory. 639f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset(); 640f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 641f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (encoder_factory && 642f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory( 643f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory->codecs())) { 644f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset( 645f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org new WebRtcSimulcastEncoderFactory(encoder_factory)); 646f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory = simulcast_encoder_factory_.get(); 647f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org } 6480a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_ = encoder_factory; 6497fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 6507fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 6510a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 6520a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 653b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 654b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 655b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 656b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 657b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 659b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 6638fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 6648fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 6658fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (codec.Matches(in)) { 6668fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 667b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 668b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 669b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 671b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 672b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 673b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 674b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 675b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// dimensions will be used for aspect ratio matching. 676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& current, 678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* out) { 67991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(out != NULL); 680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width != requested.height && 682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // 0xn and nx0 are invalid resolutions. 684b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 685b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec matching_codec; 688b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Codec not supported. 690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 693b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->id = requested.id; 694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->name = requested.name; 695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->preference = requested.preference; 696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 697ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org out->framerate = std::min(requested.framerate, matching_codec.framerate); 698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 699b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->feedback_params = requested.feedback_params; 7008fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width = requested.width; 7018fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height = requested.height; 7028fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 7038fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 7048fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 7058fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 7068fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org while (out->width > matching_codec.width) { 7078fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width /= 2; 7088fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height /= 2; 7098fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 7108fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 7118fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return out->width > 0 && out->height > 0; 712b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 713b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 714b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 715b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 716b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 717b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 718b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 719b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 720b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 721b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 722b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 723b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 724b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 725b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 7267fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstd::vector<VideoCodec> WebRtcVideoEngine2::GetSupportedCodecs() const { 72782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org std::vector<VideoCodec> supported_codecs = DefaultVideoCodecList(); 7287fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 7297fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ == NULL) { 7307fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 7317fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 7327fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 7337fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs = 7347fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->codecs(); 7357fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 7367fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Don't add internally-supported codecs twice. 7377fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecIsInternallySupported(codecs[i].name)) { 7387fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org continue; 7397fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 7407fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 741d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // External video encoders are given payloads 120-127. This also means that 742d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // we only support up to 8 external payload types. 743d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org const int kExternalVideoPayloadTypeBase = 120; 744d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org size_t payload_type = kExternalVideoPayloadTypeBase + i; 74591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(payload_type < 128); 746d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org VideoCodec codec(static_cast<int>(payload_type), 7477fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].name, 7487fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_width, 7497fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_height, 7507fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_fps, 7517fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 0); 7527fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 7537fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AddDefaultFeedbackParams(&codec); 7547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org supported_codecs.push_back(codec); 7557fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 7567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 7577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 7587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 759b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 760709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg webrtc::Call* call, 761fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org const VideoOptions& options, 762b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg const std::vector<VideoCodec>& recv_codecs, 7637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 764f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory) 765709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg : call_(call), 766709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 7677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 768f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org external_decoder_factory_(external_decoder_factory) { 76991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(thread_checker_.CalledOnValidThread()); 770fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org SetDefaultOptions(); 771fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options_.SetAll(options); 772102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (options_.cpu_overuse_detection) 773102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg signal_cpu_adaptation_ = *options_.cpu_overuse_detection; 774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 775b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 776b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 777b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg SetRecvCodecs(recv_codecs); 7786f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 7796f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 7806f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 781be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg options_.cpu_overuse_detection = rtc::Optional<bool>(true); 782be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg options_.dscp = rtc::Optional<bool>(false); 783be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg options_.suspend_below_min_bitrate = rtc::Optional<bool>(false); 784be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg options_.screencast_min_bitrate = rtc::Optional<int>(0); 785b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 786b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 787b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 788dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : send_streams_) 789dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström delete kv.second; 790dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : receive_streams_) 791dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström delete kv.second; 792b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 793b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 79496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgbool WebRtcVideoChannel2::CodecIsExternallySupported( 79596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::string& name) const { 79696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_encoder_factory_ == NULL) { 79796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 79896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 79996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 80096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec> external_codecs = 80196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_encoder_factory_->codecs(); 80296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t c = 0; c < external_codecs.size(); ++c) { 803e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(name, external_codecs[c].name)) { 80496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return true; 80596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 80696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 80796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 80896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 80996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 81096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 81196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 81296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) 81396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const { 81496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 81596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 81696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodecSettings& codec = mapped_codecs[i]; 81796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (CodecIsInternallySupported(codec.codec.name) || 81896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CodecIsExternallySupported(codec.codec.name)) { 81996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org supported_codecs.push_back(codec); 82096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 82196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 82296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return supported_codecs; 82396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 82496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 825874ca3af5b163e1b3fd8802171e44ee252557842deadbeefbool WebRtcVideoChannel2::ReceiveCodecsHaveChanged( 826874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::vector<VideoCodecSettings> before, 827874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::vector<VideoCodecSettings> after) { 828874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (before.size() != after.size()) { 829874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return true; 830874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 831874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // The receive codec order doesn't matter, so we sort the codecs before 832874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // comparing. This is necessary because currently the 833874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // only way to change the send codec is to munge SDP, which causes 834874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // the receive codec list to change order, which causes the streams 835874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // to be recreates which causes a "blink" of black video. In order 836874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // to support munging the SDP in this way without recreating receive 837874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // streams, we ignore the order of the received codecs so that 838874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // changing the order doesn't cause this "blink". 839874ca3af5b163e1b3fd8802171e44ee252557842deadbeef auto comparison = 840874ca3af5b163e1b3fd8802171e44ee252557842deadbeef [](const VideoCodecSettings& codec1, const VideoCodecSettings& codec2) { 841874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return codec1.codec.id > codec2.codec.id; 842874ca3af5b163e1b3fd8802171e44ee252557842deadbeef }; 843874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::sort(before.begin(), before.end(), comparison); 844874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::sort(after.begin(), after.end(), comparison); 845874ca3af5b163e1b3fd8802171e44ee252557842deadbeef for (size_t i = 0; i < before.size(); ++i) { 846874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // For the same reason that we sort the codecs, we also ignore the 847874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // preference. We don't want a preference change on the receive 848874ca3af5b163e1b3fd8802171e44ee252557842deadbeef // side to cause recreation of the stream. 849874ca3af5b163e1b3fd8802171e44ee252557842deadbeef before[i].codec.preference = 0; 850874ca3af5b163e1b3fd8802171e44ee252557842deadbeef after[i].codec.preference = 0; 851874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (before[i] != after[i]) { 852874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return true; 853874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 854874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 855874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return false; 856874ca3af5b163e1b3fd8802171e44ee252557842deadbeef} 857874ca3af5b163e1b3fd8802171e44ee252557842deadbeef 858c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcherbool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) { 859c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // TODO(pbos): Refactor this to only recreate the send streams once 860c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // instead of 4 times. 861c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher return (SetSendCodecs(params.codecs) && 862c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher SetSendRtpHeaderExtensions(params.extensions) && 863c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher SetMaxSendBandwidth(params.max_bandwidth_bps) && 864c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher SetOptions(params.options)); 865c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher} 866c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher 867c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcherbool WebRtcVideoChannel2::SetRecvParameters(const VideoRecvParameters& params) { 868c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // TODO(pbos): Refactor this to only recreate the recv streams once 869c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher // instead of twice. 870c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher return (SetRecvCodecs(params.codecs) && 871c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher SetRecvRtpHeaderExtensions(params.extensions)); 872c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher} 873c2ee2c86f905991a8cd05ee1f35bea105b41e4e0Peter Thatcher 874874ca3af5b163e1b3fd8802171e44ee252557842deadbeefstd::string WebRtcVideoChannel2::CodecSettingsVectorToString( 875874ca3af5b163e1b3fd8802171e44ee252557842deadbeef const std::vector<VideoCodecSettings>& codecs) { 876874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::stringstream out; 877874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << '{'; 878874ca3af5b163e1b3fd8802171e44ee252557842deadbeef for (size_t i = 0; i < codecs.size(); ++i) { 879874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << codecs[i].codec.ToString(); 880874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (i != codecs.size() - 1) { 881874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << ", "; 882874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 883874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 884874ca3af5b163e1b3fd8802171e44ee252557842deadbeef out << '}'; 885874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return out.str(); 886874ca3af5b163e1b3fd8802171e44ee252557842deadbeef} 887874ca3af5b163e1b3fd8802171e44ee252557842deadbeef 888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 88950fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvCodecs"); 890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 896b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 89796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without any video codecs."; 898b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 901874ca3af5b163e1b3fd8802171e44ee252557842deadbeef std::vector<VideoCodecSettings> supported_codecs = 90296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org FilterSupportedCodecs(mapped_codecs); 90396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 90496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (mapped_codecs.size() != supported_codecs.size()) { 90596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported video codecs."; 90696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 907b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 908b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 909ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström // Prevent reconfiguration when setting identical receive codecs. 910874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (!ReceiveCodecsHaveChanged(recv_codecs_, supported_codecs)) { 911874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) 912874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << "Ignoring call to SetRecvCodecs because codecs haven't changed."; 913874ca3af5b163e1b3fd8802171e44ee252557842deadbeef return true; 914ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström } 915ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström 916874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Changing recv codecs from " 917874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(recv_codecs_) << " to " 918874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(supported_codecs); 91996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org recv_codecs_ = supported_codecs; 920d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 921575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 9220c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = 923d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 9240c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != receive_streams_.end(); ++it) { 925d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 926d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 927d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 928b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 929b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 930b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 931b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 93250fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendCodecs"); 933b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 934b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 935b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 936b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 937b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 938b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 939b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 940b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 941b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 9423c3f6460646183914629e5dab8ae5fcede4f0e80Peter Boström LOG(LS_ERROR) << "No video codecs supported."; 943b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 944b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 945b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 946b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 947b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 948102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (send_codec_ && supported_codecs.front() == *send_codec_) { 949874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignore call to SetSendCodecs because first supported " 950874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "codec hasn't changed."; 951a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Using same codec, avoid reconfiguring. 952a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 953a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 954a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 955be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg send_codec_ = rtc::Optional<WebRtcVideoChannel2::VideoCodecSettings>( 956102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg supported_codecs.front()); 957a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 958575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 959874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Change the send codec because SetSendCodecs has a different " 960874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "first supported codec."; 961126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström for (auto& kv : send_streams_) { 96291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(kv.second != nullptr); 963126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström kv.second->SetCodec(supported_codecs.front()); 964126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström } 96543edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan LOG(LS_INFO) 96643edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << "SetFeedbackOptions on all the receive streams because the send " 96743edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan "codec has changed."; 968126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström for (auto& kv : receive_streams_) { 96991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(kv.second != nullptr); 97043edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan kv.second->SetFeedbackParameters( 97143edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan HasNack(supported_codecs.front().codec), 97243edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan HasRemb(supported_codecs.front().codec), 97343edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan HasTransportCc(supported_codecs.front().codec)); 974d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 975b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 976e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer // TODO(holmer): Changing the codec parameters shouldn't necessarily mean that 977e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer // we change the min/max of bandwidth estimation. Reevaluate this. 978008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org VideoCodec codec = supported_codecs.front().codec; 979008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org int bitrate_kbps; 980008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) && 981008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 982008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = bitrate_kbps * 1000; 983008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 984008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = 0; 985008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 986008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) && 987008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 988008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = bitrate_kbps * 1000; 989008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 990008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Do not reconfigure start bitrate unless it's specified and positive. 991008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 992008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 993008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) && 994008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 995008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = bitrate_kbps * 1000; 996008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 997008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = -1; 998008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 999008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 1000008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org 1001b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1002b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1003b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1004b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 1005102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (!send_codec_) { 1006b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 1007b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1008b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1009102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg *codec = send_codec_->codec; 1010b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1011b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1012b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 10130c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::SetSendStreamFormat(uint32_t ssrc, 1014b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1015b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 1016b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 1017575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1018b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1019b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1020b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1021b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 1022b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1023b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1024b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 1025b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 1026102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (send && !send_codec_) { 1027b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 1028b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1029b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1030b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 1031b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 1032b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1033b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 1034b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1035b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 1036b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1037b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1038b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 10390c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::SetVideoSend(uint32_t ssrc, bool enable, 10401dd98f321920c1442dd5b3f791ea0fca133c2756solenberg const VideoOptions* options) { 10411dd98f321920c1442dd5b3f791ea0fca133c2756solenberg // TODO(solenberg): The state change should be fully rolled back if any one of 10421dd98f321920c1442dd5b3f791ea0fca133c2756solenberg // these calls fail. 1043dfc8f4ff8731390828884a0a91b99e51f2950275solenberg if (!MuteStream(ssrc, !enable)) { 10441dd98f321920c1442dd5b3f791ea0fca133c2756solenberg return false; 10451dd98f321920c1442dd5b3f791ea0fca133c2756solenberg } 1046dfc8f4ff8731390828884a0a91b99e51f2950275solenberg if (enable && options) { 10471dd98f321920c1442dd5b3f791ea0fca133c2756solenberg return SetOptions(*options); 10481dd98f321920c1442dd5b3f791ea0fca133c2756solenberg } else { 10491dd98f321920c1442dd5b3f791ea0fca133c2756solenberg return true; 10501dd98f321920c1442dd5b3f791ea0fca133c2756solenberg } 10511dd98f321920c1442dd5b3f791ea0fca133c2756solenberg} 10521dd98f321920c1442dd5b3f791ea0fca133c2756solenberg 1053d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmbool WebRtcVideoChannel2::ValidateSendSsrcAvailability( 1054d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström const StreamParams& sp) const { 1055d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32_t ssrc: sp.ssrcs) { 1056d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (send_ssrcs_.find(ssrc) != send_ssrcs_.end()) { 1057d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Send stream with SSRC '" << ssrc << "' already exists."; 1058d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1059d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1060d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1061d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return true; 1062d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1063d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1064d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmbool WebRtcVideoChannel2::ValidateReceiveSsrcAvailability( 1065d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström const StreamParams& sp) const { 1066d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32_t ssrc: sp.ssrcs) { 1067d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (receive_ssrcs_.find(ssrc) != receive_ssrcs_.end()) { 1068d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Receive stream with SSRC '" << ssrc 1069d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström << "' already exists."; 1070d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1071d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1072d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1073d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return true; 1074d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1075d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1076b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 1077b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 1078d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!ValidateStreamParams(sp)) 1079b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1080b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1081575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1082d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1083d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (!ValidateSendSsrcAvailability(sp)) 1084b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1085d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 10860c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (uint32_t used_ssrc : sp.ssrcs) 1087d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström send_ssrcs_.insert(used_ssrc); 1088b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1089e5269747595864eedd604f153df5d7bcbe1b475asolenberg webrtc::VideoSendStream::Config config(this); 1090e5269747595864eedd604f153df5d7bcbe1b475asolenberg config.overuse_callback = this; 1091e5269747595864eedd604f153df5d7bcbe1b475asolenberg 1092b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoSendStream* stream = 1093709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg new WebRtcVideoSendStream(call_, 10944fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg sp, 1095e5269747595864eedd604f153df5d7bcbe1b475asolenberg config, 10967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_, 10976ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options_, 1098dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström bitrate_config_.max_bitrate_bps, 10995301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_codec_, 11005301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_rtp_extensions_); 11015301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 11020c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc = sp.first_ssrc(); 110391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(ssrc != 0); 1104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 1105b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1106b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 1107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 1108874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetLocalSsrc on all the receive streams because we added " 1109874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "a send stream."; 11103548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström for (auto& kv : receive_streams_) 11113548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström kv.second->SetLocalSsrc(ssrc); 1112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 1114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 1115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 1117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 1118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 11230c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::RemoveSendStream(uint32_t ssrc) { 1124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 1125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 1128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 1129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 1133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 1134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1136575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org WebRtcVideoSendStream* removed_stream; 1137575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org { 1138575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 11390c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 1140575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.find(ssrc); 1141575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org if (it == send_streams_.end()) { 1142575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org return false; 1143575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org } 1144575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org 11450c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (uint32_t old_ssrc : it->second->GetSsrcs()) 1146d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström send_ssrcs_.erase(old_ssrc); 1147d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1148575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org removed_stream = it->second; 1149575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.erase(it); 1150dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström 1151dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström // Switch receiver report SSRCs, the one in use is no longer valid. 1152dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström if (rtcp_receiver_report_ssrc_ == ssrc) { 1153dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström rtcp_receiver_report_ssrc_ = send_streams_.empty() 1154dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström ? kDefaultRtcpReceiverReportSsrc 1155dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström : send_streams_.begin()->first; 1156dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström LOG(LS_INFO) << "SetLocalSsrc on all the receive streams because the " 1157dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström "previous local SSRC was removed."; 1158dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström 1159dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström for (auto& kv : receive_streams_) { 1160dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström kv.second->SetLocalSsrc(rtcp_receiver_report_ssrc_); 1161dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström } 1162dfa2815b4f606a58ede5c0214e08a1d5d26d3639Peter Boström } 1163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1165575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org delete removed_stream; 1166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1167b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 1168b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 1169b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1170b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1171b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1172b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1173b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1174d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmvoid WebRtcVideoChannel2::DeleteReceiveStream( 1175d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström WebRtcVideoChannel2::WebRtcVideoReceiveStream* stream) { 11760c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (uint32_t old_ssrc : stream->GetSsrcs()) 1177d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_ssrcs_.erase(old_ssrc); 1178d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström delete stream; 1179d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1180d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 1182a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return AddRecvStream(sp, false); 1183a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 1184a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 1185a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp, 1186a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream) { 118791d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(thread_checker_.CalledOnValidThread()); 11884b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg 1189d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_INFO) << "AddRecvStream" << (default_stream ? " (default stream)" : "") 1190d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << ": " << sp.ToString(); 1191d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!ValidateStreamParams(sp)) 1192d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 1193b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 11940c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc = sp.first_ssrc(); 119591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(ssrc != 0); // TODO(pbos): Is this ever valid? 1196b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1197575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1198d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström // Remove running stream if this was a default stream. 1199d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström auto prev_stream = receive_streams_.find(ssrc); 1200d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (prev_stream != receive_streams_.end()) { 1201d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (default_stream || !prev_stream->second->IsDefaultStream()) { 1202d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Receive stream for SSRC '" << ssrc 1203d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström << "' already exists."; 1204d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1205a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org } 1206d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström DeleteReceiveStream(prev_stream->second); 1207d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_streams_.erase(prev_stream); 1208b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1209b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1210d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (!ValidateReceiveSsrcAvailability(sp)) 1211d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1212d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 12130c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (uint32_t used_ssrc : sp.ssrcs) 1214d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_ssrcs_.insert(used_ssrc); 1215d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 12164fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg webrtc::VideoReceiveStream::Config config(this); 1217d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ConfigureReceiverRtp(&config, sp); 12183bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 12198fc7fa798f7a36955f1b933980401afad2aff592pbos // Set up A/V sync group based on sync label. 12208fc7fa798f7a36955f1b933980401afad2aff592pbos config.sync_group = sp.sync_label; 12213bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 1222102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg config.rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false; 122343edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan config.rtp.transport_cc = 122443edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan send_codec_ ? HasTransportCc(send_codec_->codec) : false; 1225126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström 1226d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_streams_[ssrc] = new WebRtcVideoReceiveStream( 1227709ed67c38d0a942f3bf3e68e337cc27a27bc353Fredrik Solenberg call_, sp, config, external_decoder_factory_, default_stream, 1228d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström recv_codecs_); 1229d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1230d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1231d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1232d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1233d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 1234d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 1235d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const StreamParams& sp) const { 12360c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc = sp.first_ssrc(); 1237d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1238d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remote_ssrc = ssrc; 1239d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 1240b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1241d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 1242257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 1243b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 1244b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 1245b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 1246b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 1247d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 1248d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 1249d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 1250b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1251d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 1252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1253b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1254b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1255d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 125682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec); 1257b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1258b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 125982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 12600c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t rtx_ssrc; 126182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 126282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 126382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = 126482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org config->rtp.rtx[recv_codecs_[i].codec.id]; 126582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.ssrc = rtx_ssrc; 126682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.payload_type = recv_codecs_[i].rtx_payload_type; 126782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 126882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 1269b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1270b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 12710c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::RemoveRecvStream(uint32_t ssrc) { 1272b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 1273b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1274afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 1275afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return false; 1276b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1277b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1278575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 12790c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator stream = 1280b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 1281b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 1282b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 1283b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1284b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1285d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström DeleteReceiveStream(stream->second); 1286b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 1287b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1288b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1289b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1290b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 12910c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::SetRenderer(uint32_t ssrc, VideoRenderer* renderer) { 1292b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 1293b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 1294b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1295afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_unsignalled_ssrc_handler_.SetDefaultRenderer(this, renderer); 1296d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1297b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1298b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1299575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 13000c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = 1301d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1302d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1303d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return false; 1304b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1307b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1308b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1309b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 13100c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::GetRenderer(uint32_t ssrc, VideoRenderer** renderer) { 1311b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1312afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org *renderer = default_unsignalled_ssrc_handler_.GetDefaultRenderer(); 1313afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return *renderer != NULL; 1314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1316575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 13170c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = 1318d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1319d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1326058b1f17ac43b1fe69a8c18aaa7999ba88733dfdpbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(VideoMediaInfo* info) { 1327e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info->Clear(); 1328e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillSenderStats(info); 1329e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillReceiverStats(info); 13302b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org webrtc::Call::Stats stats = call_->GetStats(); 13312b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org FillBandwidthEstimationStats(stats, info); 13322b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org if (stats.rtt_ms != -1) { 13332b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org for (size_t i = 0; i < info->senders.size(); ++i) { 13342b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org info->senders[i].rtt_ms = stats.rtt_ms; 13352b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 13362b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 1337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1340e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 1341575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 13420c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 1343e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org send_streams_.begin(); 13440c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != send_streams_.end(); ++it) { 1345e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 1346e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1347e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1348e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1349e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 1350575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 13510c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = 1352e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org receive_streams_.begin(); 13530c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != receive_streams_.end(); ++it) { 1354e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 1355e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1356e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1357e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1358e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 13592b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org const webrtc::Call::Stats& stats, 1360e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoMediaInfo* video_media_info) { 13610bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo bwe_info; 13620bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_send_bandwidth = stats.send_bandwidth_bps; 13630bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_recv_bandwidth = stats.recv_bandwidth_bps; 13640bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.bucket_delay = stats.pacer_delay_ms; 13650bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 13660bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org // Get send stream bitrate stats. 13670bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 13680c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator stream = 13690bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org send_streams_.begin(); 13700c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström stream != send_streams_.end(); ++stream) { 13710bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stream->second->FillBandwidthEstimationInfo(&bwe_info); 13720bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 13730bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org video_media_info->bw_estimations.push_back(bwe_info); 1374e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1375e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 13760c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::SetCapturer(uint32_t ssrc, VideoCapturer* capturer) { 1377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 137991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(ssrc != 0); 1380e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1381e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope stream_lock(&stream_crit_); 1382e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (send_streams_.find(ssrc) == send_streams_.end()) { 1383e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1384e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return false; 1385e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 1386e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (!send_streams_[ssrc]->SetCapturer(capturer)) { 1387e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return false; 1388e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 138964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 139064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 139164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (capturer) { 139264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh capturer->SetApplyRotation( 139364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh !FindHeaderExtension(send_rtp_extensions_, 139464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh kRtpVideoRotationHeaderExtension)); 139564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 1396e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1397e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope lock(&capturer_crit_); 1398e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström capturers_[ssrc] = capturer; 1399e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 140064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return true; 1401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1403b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1404b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1405b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1406b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1409b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1415b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1416d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1417d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 141868786d20400f1f3744ad83549325665c18ea9e5bstefan const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, 141968786d20400f1f3744ad83549325665c18ea9e5bstefan packet_time.not_before); 14204e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 142168786d20400f1f3744ad83549325665c18ea9e5bstefan call_->Receiver()->DeliverPacket( 142268786d20400f1f3744ad83549325665c18ea9e5bstefan webrtc::MediaType::VIDEO, 142368786d20400f1f3744ad83549325665c18ea9e5bstefan reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), 142468786d20400f1f3744ad83549325665c18ea9e5bstefan webrtc_packet_time); 14254e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 14264e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 14274e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 14284e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 14294e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 14304e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 14314e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14340c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc = 0; 1435eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc)) { 1436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1439d10a68e7974a29b26d6c926e6f137255f3c173benoahric int payload_type = 0; 1440d10a68e7974a29b26d6c926e6f137255f3c173benoahric if (!GetRtpPayloadType(packet->data(), packet->size(), &payload_type)) { 1441d10a68e7974a29b26d6c926e6f137255f3c173benoahric return; 1442d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1443d10a68e7974a29b26d6c926e6f137255f3c173benoahric 1444d10a68e7974a29b26d6c926e6f137255f3c173benoahric // See if this payload_type is registered as one that usually gets its own 1445d10a68e7974a29b26d6c926e6f137255f3c173benoahric // SSRC (RTX) or at least is safe to drop either way (ULPFEC). If it is, and 1446d10a68e7974a29b26d6c926e6f137255f3c173benoahric // it wasn't handled above by DeliverPacket, that means we don't know what 1447d10a68e7974a29b26d6c926e6f137255f3c173benoahric // stream it associates with, and we shouldn't ever create an implicit channel 1448d10a68e7974a29b26d6c926e6f137255f3c173benoahric // for these. 1449d10a68e7974a29b26d6c926e6f137255f3c173benoahric for (auto& codec : recv_codecs_) { 1450d10a68e7974a29b26d6c926e6f137255f3c173benoahric if (payload_type == codec.rtx_payload_type || 1451d10a68e7974a29b26d6c926e6f137255f3c173benoahric payload_type == codec.fec.red_rtx_payload_type || 1452d10a68e7974a29b26d6c926e6f137255f3c173benoahric payload_type == codec.fec.ulpfec_payload_type) { 1453d10a68e7974a29b26d6c926e6f137255f3c173benoahric return; 1454d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1455d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1456d10a68e7974a29b26d6c926e6f137255f3c173benoahric 1457afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 1458afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDropPacket: 1459afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return; 1460afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDeliverPacket: 1461afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org break; 1462afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 1463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 146468786d20400f1f3744ad83549325665c18ea9e5bstefan if (call_->Receiver()->DeliverPacket( 146568786d20400f1f3744ad83549325665c18ea9e5bstefan webrtc::MediaType::VIDEO, 146668786d20400f1f3744ad83549325665c18ea9e5bstefan reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), 146768786d20400f1f3744ad83549325665c18ea9e5bstefan webrtc_packet_time) != webrtc::PacketReceiver::DELIVERY_OK) { 1468afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; 1469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1471b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1474d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1475d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 147668786d20400f1f3744ad83549325665c18ea9e5bstefan const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, 147768786d20400f1f3744ad83549325665c18ea9e5bstefan packet_time.not_before); 14782aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström // TODO(pbos): Check webrtc::PacketReceiver::DELIVERY_OK once we deliver 14792aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström // for both audio and video on the same path. Since BundleFilter doesn't 14802aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström // filter RTCP anymore incoming RTCP packets could've been going to audio (so 14812aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström // logging failures spam the log). 14822aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström call_->Receiver()->DeliverPacket( 14832aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström webrtc::MediaType::VIDEO, 14842aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), 14852aff615bd7c7c24a6e7a35163112f169ff4f9246Peter Boström webrtc_packet_time); 1486b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 148926c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); 1490cd6702282a49448adda470934f4bd9e6181cab22Jelena Marusic call_->SignalNetworkState(ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); 1491b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14930c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmbool WebRtcVideoChannel2::MuteStream(uint32_t ssrc, bool mute) { 1494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 149691d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(ssrc != 0); 1497575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1502ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org 1503ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org send_streams_[ssrc]->MuteStream(mute); 1504ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org return true; 1505b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1506b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1507b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1508b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 150950fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvRtpHeaderExtensions"); 1510587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " 1511587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 15123c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 15133c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1514d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1515c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::vector<webrtc::RtpExtension> filtered_extensions = 1516c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org FilterRtpExtensions(extensions); 1517874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (!RtpExtensionsHaveChanged(recv_rtp_extensions_, filtered_extensions)) { 1518874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignoring call to SetRecvRtpHeaderExtensions because " 1519874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "header extensions haven't changed."; 1520c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1521874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 1522c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1523c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org recv_rtp_extensions_ = filtered_extensions; 1524c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1525575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 15260c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = 1527d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 15280c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != receive_streams_.end(); ++it) { 1529d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 1530d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 153650fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendRtpHeaderExtensions"); 1537587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " 1538587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 15393c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 15403c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 15413c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1542c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::vector<webrtc::RtpExtension> filtered_extensions = 1543bbaf3633c54e3d49aa4c762b8eaa34e09de01c45Stefan Holmer FilterRtpExtensions(FilterRedundantRtpExtensions( 1544bbaf3633c54e3d49aa4c762b8eaa34e09de01c45Stefan Holmer extensions, kBweExtensionPriorities, kBweExtensionPrioritiesLength)); 1545874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (!RtpExtensionsHaveChanged(send_rtp_extensions_, filtered_extensions)) { 1546874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignoring call to SetSendRtpHeaderExtensions because " 1547874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "header extensions haven't changed."; 1548c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1549874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 1550c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1551c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org send_rtp_extensions_ = filtered_extensions; 1552a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 155364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const webrtc::RtpExtension* cvo_extension = FindHeaderExtension( 155464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh send_rtp_extensions_, kRtpVideoRotationHeaderExtension); 155564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 1556575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 15570c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 1558d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 15590c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != send_streams_.end(); ++it) { 1560d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 156164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh it->second->SetApplyRotation(!cvo_extension); 1562d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1563b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1564b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1566dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// Counter-intuitively this method doesn't only set global bitrate caps but also 1567dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// per-stream codec max bitrates. This is to permit SetMaxSendBitrate (b=AS) to 1568dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// raise bitrates above the 2000k default bitrate cap. 1569008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int max_bitrate_bps) { 1570dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // TODO(pbos): Figure out whether b=AS means max bitrate for this 1571dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // WebRtcVideoChannel2 (in which case we're good), or per sender (SSRC), in 1572dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // which case this should not set a Call::BitrateConfig but rather reconfigure 1573dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // all senders. 1574008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org LOG(LS_INFO) << "SetMaxSendBandwidth: " << max_bitrate_bps << "bps."; 1575dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (max_bitrate_bps == bitrate_config_.max_bitrate_bps) 1576dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return true; 1577dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 1578b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg if (max_bitrate_bps < 0) { 1579b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg // Option not set. 1580b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg return true; 1581b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg } 1582b071a19019a0a2173cc139c960d6ef6946a1c581Fredrik Solenberg if (max_bitrate_bps == 0) { 1583008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Unsetting max bitrate. 1584008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org max_bitrate_bps = -1; 1585008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1586008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 1587008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = max_bitrate_bps; 1588008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (max_bitrate_bps > 0 && 1589008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps > max_bitrate_bps) { 1590008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = max_bitrate_bps; 1591008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1592008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 1593dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström rtc::CritScope stream_lock(&stream_crit_); 1594dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : send_streams_) 1595dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström kv.second->SetMaxBitrateBps(max_bitrate_bps); 1596b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1599b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 160050fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetOptions"); 1601a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetOptions: " << options.ToString(); 1602a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoOptions old_options = options_; 1603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 1604a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (options_ == old_options) { 1605a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // No new options to set. 1606a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 1607a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1608e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1609e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope lock(&capturer_crit_); 1610102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (options_.cpu_overuse_detection) 1611102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg signal_cpu_adaptation_ = *options_.cpu_overuse_detection; 1612e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 1613102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg rtc::DiffServCodePoint dscp = 1614102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg options_.dscp.value_or(false) ? rtc::DSCP_AF41 : rtc::DSCP_DEFAULT; 1615d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org MediaChannel::SetDscp(dscp); 1616575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 16170c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 16185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_streams_.begin(); 16190c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != send_streams_.end(); ++it) { 16205301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it->second->SetOptions(options_); 16215301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1625b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1627b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1629d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Socket::OPT_RCVBUF, 1630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1632ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // Speculative change to increase the outbound socket buffer size. 1633ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // In b/15152257, we are seeing a significant number of packets discarded 1634ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // due to lack of socket buffer space, although it's not yet clear what the 1635ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // ideal value should be. 1636ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1637ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org rtc::Socket::OPT_SNDBUF, 1638ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org kVideoRtpBufferSize); 1639b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1640b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1641b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1642b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1643b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1645d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(rtc::Message* msg) { 1646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 164942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoChannel2::OnLoadUpdate(Load load) { 1650e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // OnLoadUpdate can not take any locks that are held while creating streams 1651e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // etc. Doing so establishes lock-order inversions between the webrtc process 1652e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // thread on stream creation and locks such as stream_crit_ while calling out. 1653e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope stream_lock(&capturer_crit_); 1654e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (!signal_cpu_adaptation_) 1655e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return; 1656efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng // Do not adapt resolution for screen content as this will likely result in 1657efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng // blurry and unreadable text. 1658e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström for (auto& kv : capturers_) { 1659efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng if (kv.second != nullptr 1660efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng && !kv.second->IsScreencast() 1661efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng && kv.second->video_adapter() != nullptr) { 1662e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström kv.second->video_adapter()->OnCpuResolutionRequest( 1663e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström load == kOveruse ? CoordinatedVideoAdapter::DOWNGRADE 1664e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström : CoordinatedVideoAdapter::UPGRADE); 1665e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 166642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org } 166742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 166842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 16691d8a506405734d0cef9653704b036ca4f1388960stefanbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, 16701d8a506405734d0cef9653704b036ca4f1388960stefan size_t len, 16711d8a506405734d0cef9653704b036ca4f1388960stefan const webrtc::PacketOptions& options) { 1672d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1673c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan rtc::PacketOptions rtc_options; 1674c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan rtc_options.packet_id = options.packet_id; 1675c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan return MediaChannel::SendPacket(&packet, rtc_options); 1676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1679d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1680c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan return MediaChannel::SendRtcp(&packet, rtc::PacketOptions()); 1681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1684575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 16850c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 1686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 16870c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != send_streams_.end(); ++it) { 1688b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1693575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 16940c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = 1695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 16960c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström it != send_streams_.end(); ++it) { 1697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1699b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 17016ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 17026ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 17036ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 17046ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 1705dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 1706be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg const rtc::Optional<VideoCodecSettings>& codec_settings) 1707dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström : config(config), 1708dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström options(options), 1709dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps(max_bitrate_bps), 1710102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg codec_settings(codec_settings) {} 17116ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 17124d71edef45afa38b3f68b6af0519ac0f21d327dfPeter BoströmWebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( 17134d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström webrtc::VideoEncoder* encoder, 17144d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström webrtc::VideoCodecType type, 17154d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström bool external) 17164d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström : encoder(encoder), 17174d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder(nullptr), 17184d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström type(type), 17194d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external(external) { 17204d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström if (external) { 17214d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder = encoder; 17224d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström this->encoder = 17234d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström new webrtc::VideoEncoderSoftwareFallbackWrapper(type, encoder); 17244d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström } 17254d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström} 17264d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström 1727b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1728b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 17294fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg const StreamParams& sp, 17304fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg const webrtc::VideoSendStream::Config& config, 17317fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 17326ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 1733dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 1734be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg const rtc::Optional<VideoCodecSettings>& codec_settings, 17355301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) 17367c027b64ae53a29bc528b4241cc540694c239304Henrik Kjellander : ssrcs_(sp.ssrcs), 1737259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrc_groups_(sp.ssrc_groups), 17387c027b64ae53a29bc528b4241cc540694c239304Henrik Kjellander call_(call), 17397fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 1740b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 17414fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg parameters_(config, options, max_bitrate_bps, codec_settings), 17427fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_(NULL, webrtc::kVideoCodecUnknown, false), 1743b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org capturer_(NULL), 1744b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 17459a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org muted_(false), 1746c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen old_adapt_changes_(0), 1747c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen first_frame_timestamp_ms_(0), 1748c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen last_frame_timestamp_ms_(0) { 17495301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 17505301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 17515301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 17525301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 17535301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 17545301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 17555301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 17565301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 1757102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (codec_settings) { 1758102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg SetCodec(*codec_settings); 17595301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1760b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1761b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1762b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1763b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 17645301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 17655301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org call_->DestroyVideoSendStream(stream_); 17665301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 17677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 1768b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1769b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 17704765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezstatic void CreateBlackFrame(webrtc::VideoFrame* video_frame, 1771b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1772b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1773b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->CreateEmptyFrame(width, height, width, (width + 1) / 2, 1774b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org (width + 1) / 2); 1775b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 16, 1776b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1777b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 128, 1778b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1779b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 128, 1780b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1781b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1782b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1783b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1784b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1785b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 178686196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::InputFrame"); 17874765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez webrtc::VideoFrame video_frame(frame->GetVideoFrameBuffer(), 0, 0, 17884765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez frame->GetVideoRotation()); 1789d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 17905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ == NULL) { 1791ad1f9b61a3107ca27ee023990dc576abc38f05acPeter Boström // Frame input before send codecs are configured, dropping frame. 17925301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org return; 17935301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 179486196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 179586196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // Not sending, abort early to prevent expensive reconfigurations while 179686196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // setting up codecs etc. 179786196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (!sending_) 179886196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org return; 179986196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 1800b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 180191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(format_.height == 0); 1802b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1805d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org if (muted_) { 1806d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org // Create a black frame to transmit instead. 1807afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org CreateBlackFrame(&video_frame, 1808d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetWidth()), 1809d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetHeight())); 1810d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org } 1811c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen 1812c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen int64_t frame_delta_ms = frame->GetTimeStamp() / rtc::kNumNanosecsPerMillisec; 1813c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // frame->GetTimeStamp() is essentially a delta, align to webrtc time 1814c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen if (first_frame_timestamp_ms_ == 0) { 1815c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen first_frame_timestamp_ms_ = rtc::Time() - frame_delta_ms; 1816c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen } 1817c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen 1818c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen last_frame_timestamp_ms_ = first_frame_timestamp_ms_ + frame_delta_ms; 1819c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen video_frame.set_render_time_ms(last_frame_timestamp_ms_); 1820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1821c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions( 1822afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org video_frame.width(), video_frame.height(), capturer->IsScreencast()); 1823c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1824af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(video_frame); 1825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1827b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1829b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetCapturer"); 1830b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1831b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1832b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1833b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1834b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1835d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1836b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 18371cb121dea478a4bb4f88e76cf92719e2853543cfpbos // Reset timestamps to realign new incoming frames to a webrtc timestamp. A 18381cb121dea478a4bb4f88e76cf92719e2853543cfpbos // new capturer may have a different timestamp delta than the previous one. 18391cb121dea478a4bb4f88e76cf92719e2853543cfpbos first_frame_timestamp_ms_ = 0; 18401cb121dea478a4bb4f88e76cf92719e2853543cfpbos 18419359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (capturer == NULL) { 18429359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (stream_ != NULL) { 18439359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 18444765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez webrtc::VideoFrame black_frame; 18459359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org 1846b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org CreateBlackFrame(&black_frame, last_dimensions_.width, 1847b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org last_dimensions_.height); 1848c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen 1849c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // Force this black frame not to be dropped due to timestamp order 1850c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // check. As IncomingCapturedFrame will drop the frame if this frame's 1851c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // timestamp is less than or equal to last frame's timestamp, it is 1852c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // necessary to give this black frame a larger timestamp than the 1853c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen // previous one. 1854c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen last_frame_timestamp_ms_ += 1855c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen format_.interval / rtc::kNumNanosecsPerMillisec; 1856c27d89fdc6b33846ff06e8ca8bd03119d05c6530qiangchen black_frame.set_render_time_ms(last_frame_timestamp_ms_); 1857af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(black_frame); 18589359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org } 1859b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1860b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1861b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1862b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1863b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1864b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1866b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1867b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1868b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1869b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1871b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1873b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1874b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1875b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1876b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1877b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1878b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1879b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1881d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 18856ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 1888bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.streams.back().max_framerate = 1889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1890c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions(format.width, format.height, false); 1891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1896b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1897ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1898d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1903963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org cricket::VideoCapturer* capturer; 1904963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org { 1905963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org rtc::CritScope cs(&lock_); 19069a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ == NULL) 1907963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org return false; 19089a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 19099a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) 19109a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org old_adapt_changes_ += capturer_->video_adapter()->adaptation_changes(); 19119a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 1912963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer = capturer_; 1913963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer_ = NULL; 1914b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1915963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer->SignalVideoFrame.disconnect(this); 1916b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1917b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1918b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 19190c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmconst std::vector<uint32_t>& 1920d6f4c25eedcfd502920f1b2a24744badd9da80bePeter BoströmWebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { 1921d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return ssrcs_; 1922d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1923d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 192464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shiehvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetApplyRotation( 192564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh bool apply_rotation) { 192664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh rtc::CritScope cs(&lock_); 192764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (capturer_ == NULL) 192864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return; 192964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 193064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh capturer_->SetApplyRotation(apply_rotation); 193164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh} 193264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 19335301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 19345301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1935d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1936102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (parameters_.codec_settings) { 1937874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetCodecAndOptions because of SetOptions; options=" 1938874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << options.ToString(); 1939102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg SetCodecAndOptions(*parameters_.codec_settings, options); 19405301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } else { 19415301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.options = options; 19425301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 19435301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 19447fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 1945b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 19465301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings) { 1947d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1948874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetCodecAndOptions because of SetCodec."; 19495301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 19505301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 19517fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19527fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgwebrtc::VideoCodecType CodecTypeFromName(const std::string& name) { 1953e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(name, kVp8CodecName)) { 19547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecVP8; 1955e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } else if (CodecNamesEq(name, kVp9CodecName)) { 1956188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return webrtc::kVideoCodecVP9; 1957e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } else if (CodecNamesEq(name, kH264CodecName)) { 19587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecH264; 19597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 19607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecUnknown; 19617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 19627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder 19647fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( 19657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const VideoCodec& codec) { 19667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 19677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19687fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Do not re-create encoders of the same type. 19697fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { 19707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return allocated_encoder_; 19717fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 19727fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19737fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ != NULL) { 19747fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder* encoder = 19757fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->CreateVideoEncoder(type); 19767fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder != NULL) { 19777fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(encoder, type, true); 19787fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 19797fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 19807fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 19827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder( 19837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8), type, false); 1984188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } else if (type == webrtc::kVideoCodecVP9) { 1985188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return AllocatedEncoder( 1986188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp9), type, false); 198771f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } else if (type == webrtc::kVideoCodecH264) { 198871f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin return AllocatedEncoder( 198971f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kH264), type, false); 19907fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 19917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 19937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // support. 199491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(false); 19957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(NULL, webrtc::kVideoCodecUnknown, false); 19967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 19977fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19987fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( 19997fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder* encoder) { 20007fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder->external) { 20014d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); 20027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 20034d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström delete encoder->encoder; 20047fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 20057fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 20065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 20075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings, 20085301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 2009a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org parameters_.encoder_config = 2010a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 201186196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (parameters_.encoder_config.streams.empty()) 2012b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 2013a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 20145301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 20155301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec.height, 2016b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 2017b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 20186ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 20197fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); 20207fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org parameters_.config.encoder_settings.encoder = new_encoder.encoder; 20215301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 20225301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 202347d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang if (new_encoder.external) { 202447d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang webrtc::VideoCodecType type = CodecTypeFromName(codec_settings.codec.name); 202547d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang parameters_.config.encoder_settings.internal_source = 202647d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang external_encoder_factory_->EncoderTypeHasInternalSource(type); 202747d78cc8ad54baabc9042c2b848ae3afd9b80d2esophiechang } 20285301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 20295301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 20305301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org // Set RTX payload type if RTX is enabled. 20315301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 2032b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (codec_settings.rtx_payload_type == -1) { 2033b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 2034b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type. Ignoring."; 2035b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.ssrcs.clear(); 2036b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } else { 2037b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 2038b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 20395301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 20405301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 204167c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström parameters_.config.rtp.nack.rtp_history_ms = 204267c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström HasNack(codec_settings.codec) ? kNackHistoryMs : 0; 20435301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 2044102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg RTC_CHECK(options.suspend_below_min_bitrate); 2045102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg parameters_.config.suspend_below_min_bitrate = 2046102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg *options.suspend_below_min_bitrate; 20475ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org 2048102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg parameters_.codec_settings = 2049be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg rtc::Optional<WebRtcVideoChannel2::VideoCodecSettings>(codec_settings); 20506ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 2051543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 2052874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) 2053874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << "RecreateWebRtcStream (send) because of SetCodecAndOptions; options=" 2054874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << options.ToString(); 2055b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 20567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (allocated_encoder_.encoder != new_encoder.encoder) { 20577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 20587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_ = new_encoder; 20597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2060b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2061b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2062d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 2063d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 2064d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 2065d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 2066874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (stream_ != nullptr) { 2067874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetRtpExtensions"; 20683c3f6460646183914629e5dab8ae5fcede4f0e80Peter Boström RecreateWebRtcStream(); 2069874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 2070d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2071d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2072a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgwebrtc::VideoEncoderConfig 2073a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( 2074a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const Dimensions& dimensions, 2075a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const VideoCodec& codec) const { 2076a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config; 2077a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (dimensions.is_screencast) { 2078102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg RTC_CHECK(parameters_.options.screencast_min_bitrate); 2079a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 2080102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg *parameters_.options.screencast_min_bitrate * 1000; 2081143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_config.content_type = 2082143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng webrtc::VideoEncoderConfig::ContentType::kScreen; 2083a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } else { 2084a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 0; 2085143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_config.content_type = 2086143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo; 2087a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 2088a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2089a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Restrict dimensions according to codec max. 2090a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int width = dimensions.width; 2091a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int height = dimensions.height; 2092a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (!dimensions.is_screencast) { 2093a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.width < width) 2094a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org width = codec.width; 2095a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.height < height) 2096a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org height = codec.height; 2097a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 2098a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2099a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoCodec clamped_codec = codec; 2100a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.width = width; 2101a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.height = height; 2102a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2103fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric // By default, the stream count for the codec configuration should match the 2104fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric // number of negotiated ssrcs. But if the codec is blacklisted for simulcast 2105fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric // or a screencast, only configure a single stream. 2106fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric size_t stream_count = parameters_.config.rtp.ssrcs.size(); 2107fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric if (IsCodecBlacklistedForSimulcast(codec.name) || dimensions.is_screencast) { 2108fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric stream_count = 1; 2109fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric } 2110fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric 2111fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric encoder_config.streams = 2112fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric CreateVideoStreams(clamped_codec, parameters_.options, 2113fdac516510a2bd5d57b0786fbd49e2a6b9aeed2fnoahric parameters_.max_bitrate_bps, stream_count); 2114a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2115a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Conference mode screencast uses 2 temporal layers split at 100kbit. 2116102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (parameters_.options.conference_mode.value_or(false) && 2117a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org dimensions.is_screencast && encoder_config.streams.size() == 1) { 211846d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault(); 211946d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org 212046d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // For screenshare in conference mode, tl0 and tl1 bitrates are piggybacked 212146d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // on the VideoCodec struct as target and max bitrates, respectively. 212246d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // See eg. webrtc::VP8EncoderImpl::SetRates(). 212346d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].target_bitrate_bps = 212446d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000; 212546d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].max_bitrate_bps = config.tl1_bitrate_kbps * 1000; 2126a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.clear(); 2127a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.push_back( 212846d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000); 2129a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 2130a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return encoder_config; 2131a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 2132a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2133c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( 2134c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int width, 2135c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int height, 2136efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org bool is_screencast) { 2137efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org if (last_dimensions_.width == width && last_dimensions_.height == height && 2138efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast == is_screencast) { 2139efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org // Configured using the same parameters, do not reconfigure. 2140efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org return; 2141efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org } 2142a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetDimensions: " << width << "x" << height 2143a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org << (is_screencast ? " (screencast)" : " (not screencast)"); 2144efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 2145efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.width = width; 2146efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.height = height; 2147efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast = is_screencast; 2148efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 214991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(!parameters_.encoder_config.streams.empty()); 2150c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 2151102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg RTC_CHECK(parameters_.codec_settings); 2152102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg VideoCodecSettings codec_settings = *parameters_.codec_settings; 2153c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 2154a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config = 2155a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 2156a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2157143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_config.encoder_specific_settings = ConfigureVideoEncoderSettings( 2158143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng codec_settings.codec, parameters_.options, is_screencast); 21596f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2160bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); 2161bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 2162bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = NULL; 21636f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 21646f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (!stream_reconfigured) { 2165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 2166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 2167b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 2168b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2169cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org 2170bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config = encoder_config; 2171b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2172b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2173b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 2174d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 217591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(stream_ != NULL); 2176b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 2177b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 2178b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2180b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 2181d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 21825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 21835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org stream_->Stop(); 21845301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 2185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 2186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2188e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoSenderInfo 2189e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 2190e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoSenderInfo info; 219177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org webrtc::VideoSendStream::Stats stats; 219277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org { 219377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org rtc::CritScope cs(&lock_); 219477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (uint32_t ssrc : parameters_.config.rtp.ssrcs) 219577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.add_ssrc(ssrc); 219677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 2197102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg if (parameters_.codec_settings) 2198102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg info.codec_name = parameters_.codec_settings->codec.name; 219977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (size_t i = 0; i < parameters_.encoder_config.streams.size(); ++i) { 220077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (i == parameters_.encoder_config.streams.size() - 1) { 220177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 220277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].max_bitrate_bps; 220377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } else { 220477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 220577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].target_bitrate_bps; 220677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 220777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 2208e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 220977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (stream_ == NULL) 221077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org return info; 2211c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org 221277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org stats = stream_->GetStats(); 221377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 22149a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes = old_adapt_changes_; 22159a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = CoordinatedVideoAdapter::ADAPTREASON_NONE; 22169a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 22179a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ != NULL) { 22189a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (!capturer_->IsMuted()) { 22199a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org VideoFormat last_captured_frame_format; 22209a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, &info.effects_frame_drops, 22219a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &info.capturer_frame_time, 22229a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &last_captured_frame_format); 22239a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 22249a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 22259a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 22269a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) { 22279a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes += capturer_->video_adapter()->adaptation_changes(); 22289a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = capturer_->video_adapter()->adapt_reason(); 22299a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 223077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 223177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 2232259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström info.ssrc_groups = ssrc_groups_; 2233e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_input = stats.input_frame_rate; 2234e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 22353e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.avg_encode_ms = stats.avg_encode_time_ms; 22363e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.encode_usage_percent = stats.encode_usage_percent; 2237e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 223877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.nominal_bitrate = stats.media_bitrate_bps; 223977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 2240273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_width = 0; 2241273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_height = 0; 224209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 2243e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.substreams.begin(); 224409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 2245e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 224609c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats stream_stats = it->second; 2247cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_sent += stream_stats.rtp_stats.transmitted.payload_bytes + 2248cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.header_bytes + 2249cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.padding_bytes; 2250cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_sent += stream_stats.rtp_stats.transmitted.packets; 2251e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 225209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.width > info.send_frame_width) 225309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_width = stream_stats.width; 225409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.height > info.send_frame_height) 225509c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_height = stream_stats.height; 22561d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_rcvd += stream_stats.rtcp_packet_type_counts.fir_packets; 22571d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_rcvd += stream_stats.rtcp_packet_type_counts.nack_packets; 22581d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_rcvd += stream_stats.rtcp_packet_type_counts.pli_packets; 2259e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 2260e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2261e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (!stats.substreams.empty()) { 2262e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 226309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats first_stream_stats = 226409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org stats.substreams.begin()->second; 2265e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.fraction_lost = 2266e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 2267e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org (1 << 8); 2268e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 2269e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2270e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 2271e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 2272e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 22730bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo( 22740bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo* bwe_info) { 22750bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope cs(&lock_); 22760bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org if (stream_ == NULL) { 22770bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org return; 22780bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 22790bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 228009c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 22810bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stats.substreams.begin(); 228209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 22830bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->transmit_bitrate += it->second.total_bitrate_bps; 22840bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps; 22850bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 2286891d48393e5ccd2f5e03d509c544c00a3d88cbbcpbos@webrtc.org bwe_info->target_enc_bitrate += stats.target_media_bitrate_bps; 228777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org bwe_info->actual_enc_bitrate += stats.media_bitrate_bps; 22880bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org} 22890bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 2290dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boströmvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetMaxBitrateBps( 2291dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps) { 2292dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström rtc::CritScope cs(&lock_); 2293dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström parameters_.max_bitrate_bps = max_bitrate_bps; 2294dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 2295dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // No need to reconfigure if the stream hasn't been configured yet. 2296dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (parameters_.encoder_config.streams.empty()) 2297dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return; 2298dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 2299dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // Force a stream reconfigure to set the new max bitrate. 2300dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int width = last_dimensions_.width; 2301dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström last_dimensions_.width = 0; 2302dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström SetDimensions(width, last_dimensions_.height, last_dimensions_.is_screencast); 2303dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström} 230442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 2305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 2306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 2307b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 2308b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 23096ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 2310102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg RTC_CHECK(parameters_.codec_settings); 2311bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = 2312143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng ConfigureVideoEncoderSettings( 2313102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg parameters_.codec_settings->codec, parameters_.options, 2314143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng parameters_.encoder_config.content_type == 2315143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng webrtc::VideoEncoderConfig::ContentType::kScreen); 2316bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 2317b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoSendStream::Config config = parameters_.config; 2318b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { 2319b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 2320b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type the set codec. Ignoring RTX."; 2321b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org config.rtp.rtx.ssrcs.clear(); 2322b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 2323b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org stream_ = call_->CreateVideoSendStream(config, parameters_.encoder_config); 23246f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2325bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = NULL; 23266f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 2328b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 2329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2332d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 2333d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::Call* call, 2334259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström const StreamParams& sp, 23354fbae2b79134572135d9d5fe35a7d1ccdeea3a4dsolenberg const webrtc::VideoReceiveStream::Config& config, 2336776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory, 2337a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream, 2338d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) 2339d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org : call_(call), 2340259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrcs_(sp.ssrcs), 2341259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrc_groups_(sp.ssrc_groups), 2342d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_(NULL), 2343a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org default_stream_(default_stream), 2344b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org config_(config), 2345776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_(external_decoder_factory), 2346b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org renderer_(NULL), 2347d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_(-1), 2348fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org last_height_(-1), 2349fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_(-1), 2350fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_(0) { 2351d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.renderer = this; 2352d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 2353874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "SetRecvCodecs (recv) because we are creating the receive " 2354874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "stream for the first time: " 2355874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(recv_codecs); 2356d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRecvCodecs(recv_codecs); 2357d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2358d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 23597252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter BoströmWebRtcVideoChannel2::WebRtcVideoReceiveStream::AllocatedDecoder:: 23607252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström AllocatedDecoder(webrtc::VideoDecoder* decoder, 23617252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström webrtc::VideoCodecType type, 23627252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström bool external) 23637252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström : decoder(decoder), 23647252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external_decoder(nullptr), 23657252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström type(type), 23667252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external(external) { 23677252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström if (external) { 23687252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external_decoder = decoder; 23697252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström this->decoder = 23707252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström new webrtc::VideoDecoderSoftwareFallbackWrapper(type, external_decoder); 23717252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström } 23727252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström} 23737252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström 2374d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 2375d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 237696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org ClearDecoders(&allocated_decoders_); 2377d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2378d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 23790c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmconst std::vector<uint32_t>& 2380d6f4c25eedcfd502920f1b2a24744badd9da80bePeter BoströmWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetSsrcs() const { 2381d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return ssrcs_; 2382d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 2383d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 238496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::AllocatedDecoder 238596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder( 238696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* old_decoders, 238796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodec& codec) { 238896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 2389776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 239096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < old_decoders->size(); ++i) { 239196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*old_decoders)[i].type == type) { 239296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder decoder = (*old_decoders)[i]; 239396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org (*old_decoders)[i] = old_decoders->back(); 239496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org old_decoders->pop_back(); 239596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return decoder; 239696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 239796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2398776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 239996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_decoder_factory_ != NULL) { 240096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder* decoder = 240196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_decoder_factory_->CreateVideoDecoder(type); 240296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (decoder != NULL) { 240396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(decoder, type, true); 240496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 240596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2406776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 240796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 240896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder( 240996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp8), type, false); 241096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2411d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2412b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (type == webrtc::kVideoCodecVP9) { 2413b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org return AllocatedDecoder( 2414b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp9), type, false); 2415b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 2416b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org 241771f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin if (type == webrtc::kVideoCodecH264) { 241871f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin return AllocatedDecoder( 241971f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kH264), type, false); 242071f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } 242171f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin 242296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 242396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // support. 242491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(false); 242596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(NULL, webrtc::kVideoCodecUnknown, false); 242696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 242796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 242896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 242996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 243096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder> old_decoders = allocated_decoders_; 243196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.clear(); 243296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.clear(); 243396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < recv_codecs.size(); ++i) { 243496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder allocated_decoder = 243596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CreateOrReuseVideoDecoder(&old_decoders, recv_codecs[i].codec); 243696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.push_back(allocated_decoder); 2437d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 243896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoReceiveStream::Decoder decoder; 243996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.decoder = allocated_decoder.decoder; 244096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_type = recv_codecs[i].codec.id; 244196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_name = recv_codecs[i].codec.name; 244296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.push_back(decoder); 244396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 244496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 244596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 244696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 2447257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.nack.rtp_history_ms = 2448e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin HasNack(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 2449257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 245096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org ClearDecoders(&old_decoders); 2451874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvCodecs: " 2452874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << CodecSettingsVectorToString(recv_codecs); 2453d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 2454d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2455d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 24563548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boströmvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetLocalSsrc( 24573548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström uint32_t local_ssrc) { 245891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg // TODO(pbos): Consider turning this sanity check into a RTC_DCHECK. You 245991d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg // should not be able to create a sender with the same SSRC as a receiver, but 246091d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg // right now this can't be done due to unittests depending on receiving what 246191d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg // they are sending from the same MediaChannel. 2462874ca3af5b163e1b3fd8802171e44ee252557842deadbeef if (local_ssrc == config_.rtp.remote_ssrc) { 2463874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "Ignoring call to SetLocalSsrc because parameters are " 2464874ca3af5b163e1b3fd8802171e44ee252557842deadbeef "unchanged; local_ssrc=" << local_ssrc; 24653548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström return; 2466874ca3af5b163e1b3fd8802171e44ee252557842deadbeef } 24673548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström 24683548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström config_.rtp.local_ssrc = local_ssrc; 2469874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) 2470874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << "RecreateWebRtcStream (recv) because of SetLocalSsrc; local_ssrc=" 2471874ca3af5b163e1b3fd8802171e44ee252557842deadbeef << local_ssrc; 24723548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström RecreateWebRtcStream(); 24733548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström} 24743548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström 247543edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefanvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetFeedbackParameters( 247643edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan bool nack_enabled, 247743edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan bool remb_enabled, 247843edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan bool transport_cc_enabled) { 247967c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström int nack_history_ms = nack_enabled ? kNackHistoryMs : 0; 248067c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström if (config_.rtp.nack.rtp_history_ms == nack_history_ms && 248143edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan config_.rtp.remb == remb_enabled && 248243edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan config_.rtp.transport_cc == transport_cc_enabled) { 248343edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan LOG(LS_INFO) 248443edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << "Ignoring call to SetFeedbackParameters because parameters are " 248543edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan "unchanged; nack=" 248643edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << nack_enabled << ", remb=" << remb_enabled 248743edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << ", transport_cc=" << transport_cc_enabled; 2488126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström return; 248967c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström } 249067c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström config_.rtp.remb = remb_enabled; 249167c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström config_.rtp.nack.rtp_history_ms = nack_history_ms; 249243edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan config_.rtp.transport_cc = transport_cc_enabled; 249343edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan LOG(LS_INFO) 249443edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << "RecreateWebRtcStream (recv) because of SetFeedbackParameters; nack=" 249543edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << nack_enabled << ", remb=" << remb_enabled 249643edf0ffb91a50e2efa01c7befe4d188a7e30ea2stefan << ", transport_cc=" << transport_cc_enabled; 2497126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström RecreateWebRtcStream(); 2498126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström} 2499126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström 2500d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 2501d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 2502d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.extensions = extensions; 2503874ca3af5b163e1b3fd8802171e44ee252557842deadbeef LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRtpExtensions"; 25043548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström RecreateWebRtcStream(); 2505d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2506d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2507d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 2508d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (stream_ != NULL) { 2509d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 2510d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2511d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 2512d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_->Start(); 2513d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2514d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 251596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( 251696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* allocated_decoders) { 251796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < allocated_decoders->size(); ++i) { 251896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*allocated_decoders)[i].external) { 2519776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_->DestroyVideoDecoder( 25207252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström (*allocated_decoders)[i].external_decoder); 2521776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 25227252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström delete (*allocated_decoders)[i].decoder; 2523776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 252496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders->clear(); 2525776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org} 2526776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 2527d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 25284765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez const webrtc::VideoFrame& frame, 2529d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int time_to_render_ms) { 2530d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2531fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 2532fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (first_frame_timestamp_ < 0) 2533fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_ = frame.timestamp(); 2534fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t rtp_time_elapsed_since_first_frame = 2535fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (timestamp_wraparound_handler_.Unwrap(frame.timestamp()) - 2536fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_); 2537fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t elapsed_time_ms = rtp_time_elapsed_since_first_frame / 2538fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (cricket::kVideoCodecClockrate / 1000); 2539fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (frame.ntp_time_ms() > 0) 2540fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_ = frame.ntp_time_ms() - elapsed_time_ms; 2541fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 2542d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ == NULL) { 2543d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 2544d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return; 2545d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2546d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2547d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 2548d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(frame.width(), frame.height()); 2549d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2550d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 25512386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org const WebRtcVideoFrame render_frame( 25522386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org frame.video_frame_buffer(), 255364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh frame.render_time_ms() * rtc::kNumNanosecsPerMillisec, frame.rotation()); 2554d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_->RenderFrame(&render_frame); 2555d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2556d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 25570d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsTextureSupported() const { 25580d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org return true; 25590d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org} 25600d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org 2561a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsDefaultStream() const { 2562a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return default_stream_; 2563a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 2564a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 2565d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 2566d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org cricket::VideoRenderer* renderer) { 2567d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2568d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_ = renderer; 2569d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 2570d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(last_width_, last_height_); 2571d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2572d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2573d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2574d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 2575d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 2576d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // design. 2577d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2578d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return renderer_; 2579d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2580d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2581d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 2582d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int height) { 2583d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2584d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 2585d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 2586d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2587d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_ = width; 2588d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_ = height; 2589d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2590d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2591f42376c60111edba6f29060bf3dd79e75d8dbb97pbosstd::string 2592f42376c60111edba6f29060bf3dd79e75d8dbb97pbosWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetCodecNameFromPayloadType( 2593f42376c60111edba6f29060bf3dd79e75d8dbb97pbos int payload_type) { 2594f42376c60111edba6f29060bf3dd79e75d8dbb97pbos for (const webrtc::VideoReceiveStream::Decoder& decoder : config_.decoders) { 2595f42376c60111edba6f29060bf3dd79e75d8dbb97pbos if (decoder.payload_type == payload_type) { 2596f42376c60111edba6f29060bf3dd79e75d8dbb97pbos return decoder.payload_name; 2597f42376c60111edba6f29060bf3dd79e75d8dbb97pbos } 2598f42376c60111edba6f29060bf3dd79e75d8dbb97pbos } 2599f42376c60111edba6f29060bf3dd79e75d8dbb97pbos return ""; 2600f42376c60111edba6f29060bf3dd79e75d8dbb97pbos} 2601f42376c60111edba6f29060bf3dd79e75d8dbb97pbos 2602e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoReceiverInfo 2603e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 2604e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoReceiverInfo info; 2605259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström info.ssrc_groups = ssrc_groups_; 2606e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 2607e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 2608cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_rcvd = stats.rtp_stats.transmitted.payload_bytes + 2609cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.header_bytes + 2610cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.padding_bytes; 2611cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_rcvd = stats.rtp_stats.transmitted.packets; 2612393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström info.packets_lost = stats.rtcp_stats.cumulative_lost; 2613393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström info.fraction_lost = 2614393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8); 2615e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2616e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 2617e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 2618e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_output = stats.render_frame_rate; 2619e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 26201d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org { 26211d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org rtc::CritScope frame_cs(&renderer_lock_); 26221d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_width = last_width_; 26231d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_height = last_height_; 26241d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.capture_start_ntp_time_ms = estimated_remote_start_ntp_time_ms_; 26251d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org } 26261d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org 262709c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.decode_ms = stats.decode_ms; 262809c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.max_decode_ms = stats.max_decode_ms; 262909c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.current_delay_ms = stats.current_delay_ms; 263009c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.target_delay_ms = stats.target_delay_ms; 263109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.jitter_buffer_ms = stats.jitter_buffer_ms; 263209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.min_playout_delay_ms = stats.min_playout_delay_ms; 263309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.render_delay_ms = stats.render_delay_ms; 263409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org 2635f42376c60111edba6f29060bf3dd79e75d8dbb97pbos info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type); 2636f42376c60111edba6f29060bf3dd79e75d8dbb97pbos 26371d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_sent = stats.rtcp_packet_type_counts.fir_packets; 26381d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_sent = stats.rtcp_packet_type_counts.pli_packets; 26391d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets; 2640e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2641e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 2642e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 2643e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 2645b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 2646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2647a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgbool WebRtcVideoChannel2::VideoCodecSettings::operator==( 2648a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2649a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return codec == other.codec && 2650a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && 2651a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.red_payload_type == other.fec.red_payload_type && 2652e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec.red_rtx_payload_type == other.fec.red_rtx_payload_type && 2653a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org rtx_payload_type == other.rtx_payload_type; 2654a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 2655a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2656ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boströmbool WebRtcVideoChannel2::VideoCodecSettings::operator!=( 2657ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2658ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström return !(*this == other); 2659ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström} 2660ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström 2661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 2662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 266391d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(!codecs.empty()); 2664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 2666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 2667e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 2668d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // |rtx_mapping| maps video payload type to rtx payload type. 2669d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org std::map<int, int> rtx_mapping; 2670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2671b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 2672b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2673b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 2674b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 2675b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 2676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 2678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 2679b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 2680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 2683e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 2684b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2685b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 2686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 2687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 268891d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(fec_settings.red_payload_type == -1); 2689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 2690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2693b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 2694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 269591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(fec_settings.ulpfec_payload_type == -1); 2696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 2697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2699b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 2701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 2702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 2703e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org &associated_payload_type) || 2704e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org !IsValidRtpPayloadType(associated_payload_type)) { 2705e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org LOG(LS_ERROR) 2706e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << "RTX codec with invalid or no associated payload type: " 2707e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << in_codec.ToString(); 2708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2709b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 2711b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2712b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2713b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2714b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 2715b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 2716b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2717b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2718b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 2719b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 2720b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2721b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2722b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 2723b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 272491d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg RTC_DCHECK(!video_codecs.empty()); 2725b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2726e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 2727e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org it != rtx_mapping.end(); 2728e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org ++it) { 2729e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!payload_used[it->first]) { 2730e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 2731e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2732e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2733e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO && 2734e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin payload_codec_type[it->first] != VideoCodec::CODEC_RED) { 2735e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin LOG(LS_ERROR) << "RTX not mapped to regular video codec or RED codec."; 2736e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2737e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2738e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin 2739e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (it->first == fec_settings.red_payload_type) { 2740e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec_settings.red_rtx_payload_type = it->second; 2741e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 2742e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2743e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 2744b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 2745b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 2746e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (rtx_mapping[video_codecs[i].codec.id] != 0 && 2747e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin rtx_mapping[video_codecs[i].codec.id] != 2748e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec_settings.red_payload_type) { 2749b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2750b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2751b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2752b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2753b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 2754b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2755b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2756b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 2757b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2758b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 2759