webrtcvideoengine2.cc revision cd6702282a49448adda470934f4bd9e6181cab22
1b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org/* 2b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * libjingle 3b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Copyright 2014 Google Inc. 4b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 5b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Redistribution and use in source and binary forms, with or without 6b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * modification, are permitted provided that the following conditions are met: 7b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 8b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 9b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * this list of conditions and the following disclaimer. 10b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 11b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * this list of conditions and the following disclaimer in the documentation 12b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * and/or other materials provided with the distribution. 13b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 3. The name of the author may not be used to endorse or promote products 14b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * derived from this software without specific prior written permission. 15b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 16b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org */ 27b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 28b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#ifdef HAVE_WEBRTC_VIDEO 29b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoengine2.h" 30b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 31c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org#include <algorithm> 323c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org#include <set> 33b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include <string> 34b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 35b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videocapturer.h" 36b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videorenderer.h" 37df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org#include "talk/media/webrtc/constants.h" 38a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org#include "talk/media/webrtc/simulcast.h" 3981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström#include "talk/media/webrtc/webrtcvideoencoderfactory.h" 40b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoframe.h" 41b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvoiceengine.h" 42a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/buffer.h" 43a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/logging.h" 44a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/stringutils.h" 45b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/call.h" 4671f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin#include "webrtc/modules/video_coding/codecs/h264/include/h264.h" 4781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström#include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" 4881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström#include "webrtc/system_wrappers/interface/field_trial.h" 4950fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org#include "webrtc/system_wrappers/interface/trace_event.h" 50776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org#include "webrtc/video_decoder.h" 51ab990ae43a2b84b103cb3c50bc38502375c13e68pbos@webrtc.org#include "webrtc/video_encoder.h" 52b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 53b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#define UNIMPLEMENTED \ 54b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Call to unimplemented function " << __FUNCTION__; \ 55d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg RTC_NOTREACHED() 56b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 57b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace cricket { 587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgnamespace { 5981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 6081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. 6181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmclass EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { 6281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström public: 6381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned 6481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // by e.g. PeerConnectionFactory. 6581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory) 6681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström : factory_(factory) {} 6781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström virtual ~EncoderFactoryAdapter() {} 6881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 6981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // Implement webrtc::VideoEncoderFactory. 7081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoEncoder* Create() override { 7181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->CreateVideoEncoder(webrtc::kVideoCodecVP8); 7281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 7381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 7481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström void Destroy(webrtc::VideoEncoder* encoder) override { 7581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->DestroyVideoEncoder(encoder); 7681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 7781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 7881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström private: 7981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström cricket::WebRtcVideoEncoderFactory* const factory_; 8081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström}; 8181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 8281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// An encoder factory that wraps Create requests for simulcastable codec types 8381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// with a webrtc::SimulcastEncoderAdapter. Non simulcastable codec type 8481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// requests are just passed through to the contained encoder factory. 8581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmclass WebRtcSimulcastEncoderFactory 8681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström : public cricket::WebRtcVideoEncoderFactory { 8781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström public: 8881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is 8981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // owned by e.g. PeerConnectionFactory. 9081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström explicit WebRtcSimulcastEncoderFactory( 9181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström cricket::WebRtcVideoEncoderFactory* factory) 9281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström : factory_(factory) {} 9381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 9481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström static bool UseSimulcastEncoderFactory( 9581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström const std::vector<VideoCodec>& codecs) { 9681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // If any codec is VP8, use the simulcast factory. If asked to create a 9781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // non-VP8 codec, we'll just return a contained factory encoder directly. 9881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström for (const auto& codec : codecs) { 9981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (codec.type == webrtc::kVideoCodecVP8) { 10081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return true; 10181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 10281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 10381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return false; 10481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 10581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 10681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoEncoder* CreateVideoEncoder( 10781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoCodecType type) override { 108d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(factory_ != NULL); 10981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // If it's a codec type we can simulcast, create a wrapped encoder. 11081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (type == webrtc::kVideoCodecVP8) { 11181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return new webrtc::SimulcastEncoderAdapter( 11281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström new EncoderFactoryAdapter(factory_)); 11381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 11481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoEncoder* encoder = factory_->CreateVideoEncoder(type); 11581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (encoder) { 11681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström non_simulcast_encoders_.push_back(encoder); 11781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 11881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return encoder; 11981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 12081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 12181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström const std::vector<VideoCodec>& codecs() const override { 12281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->codecs(); 12381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 12481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 12581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström bool EncoderTypeHasInternalSource( 12681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::VideoCodecType type) const override { 12781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return factory_->EncoderTypeHasInternalSource(type); 12881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 12981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 13081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override { 13181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // Check first to see if the encoder wasn't wrapped in a 13281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // SimulcastEncoderAdapter. In that case, ask the factory to destroy it. 13381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (std::remove(non_simulcast_encoders_.begin(), 13481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström non_simulcast_encoders_.end(), 13581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström encoder) != non_simulcast_encoders_.end()) { 13681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström factory_->DestroyVideoEncoder(encoder); 13781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return; 13881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 13981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 14081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // Otherwise, SimulcastEncoderAdapter can be deleted directly, and will call 14181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // DestroyVideoEncoder on the factory for individual encoder instances. 14281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström delete encoder; 14381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 14481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 14581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström private: 14681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström cricket::WebRtcVideoEncoderFactory* factory_; 14781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // A list of encoders that were created without being wrapped in a 14881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // SimulcastEncoderAdapter. 14981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström std::vector<webrtc::VideoEncoder*> non_simulcast_encoders_; 15081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström}; 15181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 15281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmbool CodecIsInternallySupported(const std::string& codec_name) { 15381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (CodecNamesEq(codec_name, kVp8CodecName)) { 15481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return true; 15581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 15681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (CodecNamesEq(codec_name, kVp9CodecName)) { 15781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström const std::string group_name = 15881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström webrtc::field_trial::FindFullName("WebRTC-SupportVP9"); 15981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return group_name == "Enabled" || group_name == "EnabledByFlag"; 16081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 16171f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin if (CodecNamesEq(codec_name, kH264CodecName)) { 16271f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin return webrtc::H264Encoder::IsSupported() && 16371f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin webrtc::H264Decoder::IsSupported(); 16471f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } 16581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return false; 16681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 16781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 16881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmvoid AddDefaultFeedbackParams(VideoCodec* codec) { 16981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); 17081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); 17181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); 17281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); 17381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 17481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 17581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmstatic VideoCodec MakeVideoCodecWithDefaultFeedbackParams(int payload_type, 17681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström const char* name) { 17781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström VideoCodec codec(payload_type, name, kDefaultVideoMaxWidth, 17881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström kDefaultVideoMaxHeight, kDefaultVideoMaxFramerate, 0); 17981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström AddDefaultFeedbackParams(&codec); 18081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return codec; 18181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 18281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 1837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { 1847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::stringstream out; 1857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '{'; 1867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 1877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << codecs[i].ToString(); 1887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (i != codecs.size() - 1) { 1897fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << ", "; 1907fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '}'; 1937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return out.str(); 1947fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 1957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 1967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic bool ValidateCodecFormats(const std::vector<VideoCodec>& codecs) { 1977fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org bool has_video = false; 1987fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 1997fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!codecs[i].ValidateCodecFormat()) { 2007fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return false; 2017fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (codecs[i].GetCodecType() == VideoCodec::CODEC_VIDEO) { 2037fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org has_video = true; 2047fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2057fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2067fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!has_video) { 2077fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org LOG(LS_ERROR) << "Setting codecs without a video codec is invalid: " 2087fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org << CodecVectorToString(codecs); 2097fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return false; 2107fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2117fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return true; 2127fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 2137fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 214d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boströmstatic bool ValidateStreamParams(const StreamParams& sp) { 215d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (sp.ssrcs.empty()) { 216d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); 217d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 218d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 219d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 220d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström std::vector<uint32> primary_ssrcs; 221d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström sp.GetPrimarySsrcs(&primary_ssrcs); 222d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström std::vector<uint32> rtx_ssrcs; 223d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström sp.GetFidSsrcs(primary_ssrcs, &rtx_ssrcs); 224d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström for (uint32_t rtx_ssrc : rtx_ssrcs) { 225d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström bool rtx_ssrc_present = false; 226d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström for (uint32_t sp_ssrc : sp.ssrcs) { 227d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (sp_ssrc == rtx_ssrc) { 228d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström rtx_ssrc_present = true; 229d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström break; 230d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 231d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 232d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!rtx_ssrc_present) { 233d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) << "RTX SSRC '" << rtx_ssrc 234d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << "' missing from StreamParams ssrcs: " << sp.ToString(); 235d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 236d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 237d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 238d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 239d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) 240d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 241d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << sp.ToString(); 242d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 243d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 244d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 245d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return true; 246d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström} 247d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 2487fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic std::string RtpExtensionsToString( 2497fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 2507fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::stringstream out; 2517fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '{'; 2527fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 2537fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; 2547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (i != extensions.size() - 1) { 2557fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << ", "; 2567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '}'; 2597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return out.str(); 2607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 2617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 26264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shiehinline const webrtc::RtpExtension* FindHeaderExtension( 26364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const std::vector<webrtc::RtpExtension>& extensions, 26464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const std::string& name) { 26564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh for (const auto& kv : extensions) { 26664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (kv.name == name) { 26764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return &kv; 26864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 26964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 27064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return NULL; 27164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh} 27264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 27382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org// Merges two fec configs and logs an error if a conflict arises 274e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin// such that merging in different order would trigger a different output. 27582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.orgstatic void MergeFecConfig(const webrtc::FecConfig& other, 27682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::FecConfig* output) { 27782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.ulpfec_payload_type != -1) { 27882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->ulpfec_payload_type != -1 && 27982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type != other.ulpfec_payload_type) { 28082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: " 28182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->ulpfec_payload_type << " and " 28282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.ulpfec_payload_type; 28382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 28482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type = other.ulpfec_payload_type; 28582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 28682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.red_payload_type != -1) { 28782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->red_payload_type != -1 && 28882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type != other.red_payload_type) { 28982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging red_payload_type configs: " 29082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->red_payload_type << " and " 29182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.red_payload_type; 29282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 29382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type = other.red_payload_type; 29482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 295e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (other.red_rtx_payload_type != -1) { 296e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (output->red_rtx_payload_type != -1 && 297e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin output->red_rtx_payload_type != other.red_rtx_payload_type) { 298e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin LOG(LS_WARNING) << "Conflict merging red_rtx_payload_type configs: " 299e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin << output->red_rtx_payload_type << " and " 300e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin << other.red_rtx_payload_type; 301e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 302e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin output->red_rtx_payload_type = other.red_rtx_payload_type; 303e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 30482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org} 3057fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} // namespace 306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 30781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// Constants defined in talk/media/webrtc/constants.h 30881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström// TODO(pbos): Move these to a separate constants.cc file. 30981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kMinVideoBitrate = 30; 31081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kStartVideoBitrate = 300; 31181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kMaxVideoBitrate = 2000; 31281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 31381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kVideoMtu = 1200; 31481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmconst int kVideoRtpBufferSize = 65536; 31581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 316b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 317b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// duration hasn't been implemented. 318b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 320933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.orgstatic const int kDefaultQpMax = 56; 321933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org 322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 324e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmerconst int kMinBandwidthBps = 30000; 325e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmerconst int kStartBandwidthBps = 300000; 326e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmerconst int kMaxBandwidthBps = 2000000; 327e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer 32881ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boströmstd::vector<VideoCodec> DefaultVideoCodecList() { 32981ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström std::vector<VideoCodec> codecs; 33081ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström if (CodecIsInternallySupported(kVp9CodecName)) { 33181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp9PlType, 33281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström kVp9CodecName)); 33381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström // TODO(andresp): Add rtx codec for vp9 and verify it works. 33481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström } 33581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, 33681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström kVp8CodecName)); 33771f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin if (CodecIsInternallySupported(kH264CodecName)) { 33871f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin codecs.push_back(MakeVideoCodecWithDefaultFeedbackParams(kDefaultH264PlType, 33971f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin kH264CodecName)); 34071f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } 34181ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back( 34281ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström VideoCodec::CreateRtxCodec(kDefaultRtxVp8PlType, kDefaultVp8PlType)); 34381ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(VideoCodec(kDefaultRedPlType, kRedCodecName)); 34481ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName)); 34581ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström return codecs; 34681ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström} 34781ea54eaac82b36b7208a02fd37a469d7d0bd9d0Peter Boström 348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& requested_codec, 350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* matching_codec) { 351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *matching_codec = codecs[i]; 354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 3603c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic bool ValidateRtpHeaderExtensionIds( 3613c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 3623c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::set<int> extensions_used; 3633c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 36423914fe756903353eae13fffc868d2c84f51f06fPeter Boström if (extensions[i].id <= 0 || extensions[i].id >= 15 || 3653c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org !extensions_used.insert(extensions[i].id).second) { 3663c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; 3673c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 3683c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 3693c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 3703c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return true; 3713c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 3723c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 373c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.orgstatic bool CompareRtpHeaderExtensionIds( 374c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const webrtc::RtpExtension& extension1, 375c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const webrtc::RtpExtension& extension2) { 376c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // Sorting on ID is sufficient, more than one extension per ID is unsupported. 377c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return extension1.id > extension2.id; 378c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org} 379c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 3803c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic std::vector<webrtc::RtpExtension> FilterRtpExtensions( 3813c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 3823c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::vector<webrtc::RtpExtension> webrtc_extensions; 3833c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 3843c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org // Unsupported extensions will be ignored. 38523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg if (webrtc::RtpExtension::IsSupportedForVideo(extensions[i].uri)) { 3863c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org webrtc_extensions.push_back(webrtc::RtpExtension( 3873c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org extensions[i].uri, extensions[i].id)); 3883c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } else { 3893c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; 3903c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 3913c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 392c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 393c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // Sort filtered headers to make sure that they can later be compared 394c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // regardless of in which order they were entered. 395c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::sort(webrtc_extensions.begin(), webrtc_extensions.end(), 396c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org CompareRtpHeaderExtensionIds); 3973c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return webrtc_extensions; 3983c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 3993c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 400c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.orgstatic bool RtpExtensionsHaveChanged( 401c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const std::vector<webrtc::RtpExtension>& before, 402c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const std::vector<webrtc::RtpExtension>& after) { 403c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before.size() != after.size()) 404c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 405c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org for (size_t i = 0; i < before.size(); ++i) { 406c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before[i].id != after[i].id) 407c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 408c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before[i].name != after[i].name) 409c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 410c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org } 411c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return false; 412c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org} 413c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 414a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.orgstd::vector<webrtc::VideoStream> 415f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateSimulcastVideoStreams( 416d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 417d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 418dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 419d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 420a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org int max_qp = kDefaultQpMax; 421a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 422a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 423a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org return GetSimulcastConfig( 424dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström num_streams, GetSimulcastBitrateMode(options), codec.width, codec.height, 425dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps, max_qp, 426a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate); 427a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org} 428a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 429f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgstd::vector<webrtc::VideoStream> 430f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoStreams( 431a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoCodec& codec, 432a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoOptions& options, 433dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 434a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org size_t num_streams) { 435dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int codec_max_bitrate_kbps; 436dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (codec.GetParam(kCodecParamMaxBitrate, &codec_max_bitrate_kbps)) { 437dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps = codec_max_bitrate_kbps * 1000; 438dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström } 439dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (num_streams != 1) { 440dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return CreateSimulcastVideoStreams(codec, options, max_bitrate_bps, 441dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström num_streams); 442dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström } 443dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 444dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // For unset max bitrates set default bitrate for non-simulcast. 445dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (max_bitrate_bps <= 0) 446dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps = kMaxVideoBitrate * 1000; 447a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 448d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 449d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 450d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 451d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 45282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate; 453d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 454008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org stream.min_bitrate_bps = kMinVideoBitrate * 1000; 455dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate_bps; 456d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 457933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org int max_qp = kDefaultQpMax; 458d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 459d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 460d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 461d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 462d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 463d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 465f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgvoid* WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( 4666f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 467143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng const VideoOptions& options, 468143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng bool is_screencast) { 469143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng // No automatic resizing when using simulcast. 470143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng bool automatic_resize = !is_screencast && ssrcs_.size() == 1; 471143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng bool frame_dropping = !is_screencast; 472143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng bool denoising; 473143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng if (is_screencast) { 474143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng denoising = false; 475143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng } else { 476143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng options.video_noise_reduction.Get(&denoising); 477143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng } 478143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng 479e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(codec.name, kVp8CodecName)) { 480f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp8 = webrtc::VideoEncoder::GetDefaultVp8Settings(); 481143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp8.automaticResizeOn = automatic_resize; 482143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp8.denoisingOn = denoising; 483143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp8.frameDroppingOn = frame_dropping; 484f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp8; 4856f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 486e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(codec.name, kVp9CodecName)) { 487f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp9 = webrtc::VideoEncoder::GetDefaultVp9Settings(); 488143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp9.denoisingOn = denoising; 489143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_settings_.vp9.frameDroppingOn = frame_dropping; 490f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp9; 491188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } 4926f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 4936f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 4946f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 495afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgDefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler() 496afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org : default_recv_ssrc_(0), default_renderer_(NULL) {} 497afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 498afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgUnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc( 499a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org WebRtcVideoChannel2* channel, 500afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org uint32_t ssrc) { 501afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 502afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 503afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDropPacket; 504afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 505afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 506afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org StreamParams sp; 507afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org sp.ssrcs.push_back(ssrc); 508afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 509a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org if (!channel->AddRecvStream(sp, true)) { 510afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Could not create default receive stream."; 511afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 512afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 513afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(ssrc, default_renderer_); 514afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_recv_ssrc_ = ssrc; 515afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDeliverPacket; 516afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 517afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 51842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgWebRtcCallFactory::~WebRtcCallFactory() { 51942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 52042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgwebrtc::Call* WebRtcCallFactory::CreateCall( 52142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org const webrtc::Call::Config& config) { 52242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org return webrtc::Call::Create(config); 52342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 52442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 525afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgVideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { 526afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return default_renderer_; 527afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 528afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 529afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgvoid DefaultUnsignalledSsrcHandler::SetDefaultRenderer( 530afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 531afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoRenderer* renderer) { 532afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_renderer_ = renderer; 533afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { 534afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(default_recv_ssrc_, default_renderer_); 535afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 536afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 537afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 538f1f0d9a4cd53f4eacbf791cb7317612fa7382a45pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2(WebRtcVoiceEngine* voice_engine) 5399a416bd14ee225d8f1a1ada627a1dd7daf275032Fredrik Solenberg : voice_engine_(voice_engine), 540b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org initialized_(false), 54142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_factory_(&default_call_factory_), 5420a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_(NULL), 5430a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_(NULL) { 544b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; 5457fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 546587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 547587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 548587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpTimestampOffsetHeaderExtensionDefaultId)); 549587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 550587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 551587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 55264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh rtp_header_extensions_.push_back( 55364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh RtpHeaderExtension(kRtpVideoRotationHeaderExtension, 55464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh kRtpVideoRotationHeaderExtensionDefaultId)); 555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 556b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 557b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 560b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 56142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoEngine2::SetCallFactory(WebRtcCallFactory* call_factory) { 562d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!initialized_); 56342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_factory_ = call_factory; 56442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 56542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 5669a416bd14ee225d8f1a1ada627a1dd7daf275032Fredrik Solenbergvoid WebRtcVideoEngine2::Init() { 567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgint WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } 572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoEncoderConfig& config) { 5758fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org const VideoCodec& codec = config.max_codec; 576957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org bool supports_codec = false; 577957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org for (size_t i = 0; i < video_codecs_.size(); ++i) { 578e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(video_codecs_[i].name, codec.name)) { 5792a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].width = codec.width; 5802a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].height = codec.height; 5812a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].framerate = codec.framerate; 582957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org supports_codec = true; 583957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org break; 584957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org } 585957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org } 586957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org 587957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org if (!supports_codec) { 588957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported: " 5898fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org << codec.ToString(); 5908fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return false; 5918fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 5928fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 593b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 594b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 595b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 596b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 5971ecbe45c7e4c9142896cb2810d699558518f4f28buildbot@webrtc.org const VideoOptions& options, 598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel) { 599d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(initialized_); 600b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "CreateChannel: " 601b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (voice_channel != NULL ? "With" : "Without") 602fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org << " voice channel. Options: " << options.ToString(); 6037fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoChannel2* channel = 6044b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg new WebRtcVideoChannel2(call_factory_, voice_engine_, 6054b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg static_cast<WebRtcVoiceMediaChannel*>(voice_channel), options, 6064b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg external_encoder_factory_, external_decoder_factory_); 607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!channel->Init()) { 608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete channel; 609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 611e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org channel->SetRecvCodecs(video_codecs_); 612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return channel; 613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 618b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return rtp_header_extensions_; 622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { 625b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Set up logging. 626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; 627b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if min_sev == -1, we keep the current log level. 628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (min_sev < 0) { 629d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(min_sev == -1); 630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 632b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 633b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 6340a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalDecoderFactory( 6350a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoDecoderFactory* decoder_factory) { 636d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!initialized_); 6370a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_ = decoder_factory; 6380a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 6390a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 6400a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalEncoderFactory( 6410a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoEncoderFactory* encoder_factory) { 642d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!initialized_); 643f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (external_encoder_factory_ == encoder_factory) 644f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org return; 645f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 646f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // No matter what happens we shouldn't hold on to a stale 647f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // WebRtcSimulcastEncoderFactory. 648f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset(); 649f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 650f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (encoder_factory && 651f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory( 652f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory->codecs())) { 653f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset( 654f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org new WebRtcSimulcastEncoderFactory(encoder_factory)); 655f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory = simulcast_encoder_factory_.get(); 656f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org } 6570a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_ = encoder_factory; 6587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 6597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 6600a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 6610a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 667b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 668b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 669b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 671b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 6728fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 6738fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 6748fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (codec.Matches(in)) { 6758fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 679b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 684b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// dimensions will be used for aspect ratio matching. 685b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& current, 687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* out) { 688d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(out != NULL); 689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width != requested.height && 691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // 0xn and nx0 are invalid resolutions. 693b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec matching_codec; 697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Codec not supported. 699b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->id = requested.id; 703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->name = requested.name; 704b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->preference = requested.preference; 705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 706ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org out->framerate = std::min(requested.framerate, matching_codec.framerate); 707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->feedback_params = requested.feedback_params; 7098fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width = requested.width; 7108fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height = requested.height; 7118fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 7128fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 7138fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 7148fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 7158fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org while (out->width > matching_codec.width) { 7168fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width /= 2; 7178fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height /= 2; 7188fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 7198fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 7208fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return out->width > 0 && out->height > 0; 721b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 722b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 723b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 724b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 725b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 726b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 727b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 728b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 729b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 730b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 731b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 732b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 733b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 734b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 7357fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstd::vector<VideoCodec> WebRtcVideoEngine2::GetSupportedCodecs() const { 73682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org std::vector<VideoCodec> supported_codecs = DefaultVideoCodecList(); 7377fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 7387fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ == NULL) { 7397fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 7407fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 7417fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 7427fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs = 7437fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->codecs(); 7447fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 7457fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Don't add internally-supported codecs twice. 7467fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecIsInternallySupported(codecs[i].name)) { 7477fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org continue; 7487fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 7497fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 750d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // External video encoders are given payloads 120-127. This also means that 751d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // we only support up to 8 external payload types. 752d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org const int kExternalVideoPayloadTypeBase = 120; 753d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org size_t payload_type = kExternalVideoPayloadTypeBase + i; 754d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(payload_type < 128); 755d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org VideoCodec codec(static_cast<int>(payload_type), 7567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].name, 7577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_width, 7587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_height, 7597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_fps, 7607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 0); 7617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 7627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AddDefaultFeedbackParams(&codec); 7637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org supported_codecs.push_back(codec); 7647fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 7657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 7667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 7677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 768b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 76942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org WebRtcCallFactory* call_factory, 7703bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org WebRtcVoiceEngine* voice_engine, 7714b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg WebRtcVoiceMediaChannel* voice_channel, 772fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org const VideoOptions& options, 7737fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 774f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory) 775b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 7764b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg voice_channel_(voice_channel), 7774b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg voice_channel_id_(voice_channel ? voice_channel->voe_channel() : -1), 7787fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 779f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org external_decoder_factory_(external_decoder_factory) { 7804b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg DCHECK(thread_checker_.CalledOnValidThread()); 781fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org SetDefaultOptions(); 782fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options_.SetAll(options); 783e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström options_.cpu_overuse_detection.Get(&signal_cpu_adaptation_); 784b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call::Config config(this); 78542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org config.overuse_callback = this; 7863bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org if (voice_engine != NULL) { 7873bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org config.voice_engine = voice_engine->voe()->engine(); 7883bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org } 789e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer config.bitrate_config.min_bitrate_bps = kMinBandwidthBps; 790e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer config.bitrate_config.start_bitrate_bps = kStartBandwidthBps; 791e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer config.bitrate_config.max_bitrate_bps = kMaxBandwidthBps; 79242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_.reset(call_factory->CreateCall(config)); 7934b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg if (voice_channel_) { 7944b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg voice_channel_->SetCall(call_.get()); 7954b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg } 796b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 797b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 798b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 7996f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 8006f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 8016f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 802e432800aeb6b695bda14acf2d60c0200803b5218Peter Boström options_.cpu_overuse_detection.Set(true); 803d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org options_.dscp.Set(false); 8045ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options_.suspend_below_min_bitrate.Set(false); 80542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org options_.video_noise_reduction.Set(true); 806efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org options_.screencast_min_bitrate.Set(0); 807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 8104b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg DetachVoiceChannel(); 811dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : send_streams_) 812dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström delete kv.second; 813dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : receive_streams_) 814dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström delete kv.second; 815b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::Init() { return true; } 818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 8194b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenbergvoid WebRtcVideoChannel2::DetachVoiceChannel() { 8204b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg DCHECK(thread_checker_.CalledOnValidThread()); 8214b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg if (voice_channel_) { 8224b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg voice_channel_->SetCall(nullptr); 8234b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg voice_channel_ = nullptr; 8244b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg } 8254b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg} 8264b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg 82796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgbool WebRtcVideoChannel2::CodecIsExternallySupported( 82896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::string& name) const { 82996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_encoder_factory_ == NULL) { 83096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 83196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 83296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 83396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec> external_codecs = 83496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_encoder_factory_->codecs(); 83596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t c = 0; c < external_codecs.size(); ++c) { 836e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(name, external_codecs[c].name)) { 83796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return true; 83896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 83996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 84096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 84196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 84296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 84396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 84496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 84596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) 84696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const { 84796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 84896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 84996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodecSettings& codec = mapped_codecs[i]; 85096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (CodecIsInternallySupported(codec.codec.name) || 85196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CodecIsExternallySupported(codec.codec.name)) { 85296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org supported_codecs.push_back(codec); 85396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 85496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 85596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return supported_codecs; 85696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 85796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 858b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 85950fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvCodecs"); 860b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 861b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 862b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 863b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 864b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 866b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 86796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without any video codecs."; 868b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 869b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 87196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 87296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org FilterSupportedCodecs(mapped_codecs); 87396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 87496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (mapped_codecs.size() != supported_codecs.size()) { 87596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported video codecs."; 87696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 877b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 878b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 879ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström // Prevent reconfiguration when setting identical receive codecs. 880ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström if (recv_codecs_.size() == supported_codecs.size()) { 881ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström bool reconfigured = false; 882ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström for (size_t i = 0; i < supported_codecs.size(); ++i) { 883ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström if (recv_codecs_[i] != supported_codecs[i]) { 884ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström reconfigured = true; 885ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström break; 886ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström } 887ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström } 888ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström if (!reconfigured) 889ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström return true; 890ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström } 891ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström 89296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org recv_codecs_ = supported_codecs; 893d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 894575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 895d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 896d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 897d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 898d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 899d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 900d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 901d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 905b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 90650fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendCodecs"); 907b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 908b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 909b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 910b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 911b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 912b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 913b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 914b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 915b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 9163c3f6460646183914629e5dab8ae5fcede4f0e80Peter Boström LOG(LS_ERROR) << "No video codecs supported."; 917b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 918b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 919b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 920b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 921b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 922a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoCodecSettings old_codec; 923a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (send_codec_.Get(&old_codec) && supported_codecs.front() == old_codec) { 924a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Using same codec, avoid reconfiguring. 925a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 926a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 927a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 928a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org send_codec_.Set(supported_codecs.front()); 929a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 930575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 931126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström for (auto& kv : send_streams_) { 932126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström DCHECK(kv.second != nullptr); 933126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström kv.second->SetCodec(supported_codecs.front()); 934126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström } 935126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström for (auto& kv : receive_streams_) { 936126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström DCHECK(kv.second != nullptr); 93767c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström kv.second->SetNackAndRemb(HasNack(supported_codecs.front().codec), 93867c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström HasRemb(supported_codecs.front().codec)); 939d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 940b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 941e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer // TODO(holmer): Changing the codec parameters shouldn't necessarily mean that 942e59041672283a28bde0b043c0c2bc198272f82e1Stefan Holmer // we change the min/max of bandwidth estimation. Reevaluate this. 943008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org VideoCodec codec = supported_codecs.front().codec; 944008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org int bitrate_kbps; 945008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) && 946008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 947008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = bitrate_kbps * 1000; 948008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 949008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = 0; 950008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 951008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) && 952008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 953008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = bitrate_kbps * 1000; 954008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 955008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Do not reconfigure start bitrate unless it's specified and positive. 956008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 957008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 958008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) && 959008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 960008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = bitrate_kbps * 1000; 961008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 962008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = -1; 963008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 964008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 965008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org 966b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 967b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 968b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 969b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 970b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodecSettings codec_settings; 971b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 972b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 973b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 974b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 975b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *codec = codec_settings.codec; 976b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 977b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 978b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 979b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, 980b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 981b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 982b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 983575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 984b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 985b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 986b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 987b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 988b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 989b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 990b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRender(bool render) { 991b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. 992b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); 993b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 994b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 995b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 996b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 997b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 998b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send && !send_codec_.IsSet()) { 999b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 1000b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1001b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1002b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 1003b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 1004b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1005b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 1006b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1007b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 1008b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1009b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1010b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1011d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmbool WebRtcVideoChannel2::ValidateSendSsrcAvailability( 1012d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström const StreamParams& sp) const { 1013d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32_t ssrc: sp.ssrcs) { 1014d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (send_ssrcs_.find(ssrc) != send_ssrcs_.end()) { 1015d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Send stream with SSRC '" << ssrc << "' already exists."; 1016d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1017d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1018d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1019d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return true; 1020d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1021d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1022d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmbool WebRtcVideoChannel2::ValidateReceiveSsrcAvailability( 1023d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström const StreamParams& sp) const { 1024d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32_t ssrc: sp.ssrcs) { 1025d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (receive_ssrcs_.find(ssrc) != receive_ssrcs_.end()) { 1026d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Receive stream with SSRC '" << ssrc 1027d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström << "' already exists."; 1028d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1029d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1030d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström } 1031d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return true; 1032d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1033d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1034b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 1035b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 1036d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!ValidateStreamParams(sp)) 1037b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1038b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1039575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1040d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1041d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (!ValidateSendSsrcAvailability(sp)) 1042b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1043d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1044d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32 used_ssrc : sp.ssrcs) 1045d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström send_ssrcs_.insert(used_ssrc); 1046b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1047b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoSendStream* stream = 10486ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org new WebRtcVideoSendStream(call_.get(), 10497fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_, 10506ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options_, 1051dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström bitrate_config_.max_bitrate_bps, 10525301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_codec_, 10535301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp, 10545301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_rtp_extensions_); 10555301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 1056d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström uint32 ssrc = sp.first_ssrc(); 1057d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(ssrc != 0); 1058b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 1059b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1060b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 1061b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 10623548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström for (auto& kv : receive_streams_) 10633548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström kv.second->SetLocalSsrc(ssrc); 1064b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1065b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 1066b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 1067b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1068b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 1069b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 1070b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1071b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1072b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1073b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1074b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1075b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { 1076b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 1077b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1078b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1079b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 1080b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 1081b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1082b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1083b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1084b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 1085b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 1086b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1087b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1088575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org WebRtcVideoSendStream* removed_stream; 1089575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org { 1090575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1091575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1092575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.find(ssrc); 1093575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org if (it == send_streams_.end()) { 1094575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org return false; 1095575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org } 1096575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org 1097d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32 old_ssrc : it->second->GetSsrcs()) 1098d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström send_ssrcs_.erase(old_ssrc); 1099d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1100575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org removed_stream = it->second; 1101575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.erase(it); 1102b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1103b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1104575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org delete removed_stream; 1105b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1106b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 1107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 1108b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1109b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1111b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1113d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmvoid WebRtcVideoChannel2::DeleteReceiveStream( 1114d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström WebRtcVideoChannel2::WebRtcVideoReceiveStream* stream) { 1115d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32 old_ssrc : stream->GetSsrcs()) 1116d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_ssrcs_.erase(old_ssrc); 1117d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström delete stream; 1118d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1119d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 1121a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return AddRecvStream(sp, false); 1122a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 1123a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 1124a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp, 1125a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream) { 11264b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg DCHECK(thread_checker_.CalledOnValidThread()); 11274b60c73e74d62beff484b7f54d8f3267cb66274fFredrik Solenberg 1128d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_INFO) << "AddRecvStream" << (default_stream ? " (default stream)" : "") 1129d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << ": " << sp.ToString(); 1130d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!ValidateStreamParams(sp)) 1131d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 1132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 1134d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(ssrc != 0); // TODO(pbos): Is this ever valid? 1135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1136575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1137d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström // Remove running stream if this was a default stream. 1138d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström auto prev_stream = receive_streams_.find(ssrc); 1139d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (prev_stream != receive_streams_.end()) { 1140d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (default_stream || !prev_stream->second->IsDefaultStream()) { 1141d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström LOG(LS_ERROR) << "Receive stream for SSRC '" << ssrc 1142d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström << "' already exists."; 1143d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1144a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org } 1145d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström DeleteReceiveStream(prev_stream->second); 1146d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_streams_.erase(prev_stream); 1147b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1148b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1149d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström if (!ValidateReceiveSsrcAvailability(sp)) 1150d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return false; 1151d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1152d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström for (uint32 used_ssrc : sp.ssrcs) 1153d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_ssrcs_.insert(used_ssrc); 1154d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 1155bd249bc711b3c9efd142eb8de3df489282fe693epbos@webrtc.org webrtc::VideoReceiveStream::Config config; 1156d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ConfigureReceiverRtp(&config, sp); 11573bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 11588fc7fa798f7a36955f1b933980401afad2aff592pbos // Set up A/V sync group based on sync label. 11598fc7fa798f7a36955f1b933980401afad2aff592pbos config.sync_group = sp.sync_label; 11603bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 1161126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström config.rtp.remb = false; 1162126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström VideoCodecSettings send_codec; 1163126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström if (send_codec_.Get(&send_codec)) { 1164126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström config.rtp.remb = HasRemb(send_codec.codec); 1165126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström } 1166126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström 1167d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström receive_streams_[ssrc] = new WebRtcVideoReceiveStream( 1168259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström call_.get(), sp, external_decoder_factory_, default_stream, config, 1169d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström recv_codecs_); 1170d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1171d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1172d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1173d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1174d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 1175d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 1176d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const StreamParams& sp) const { 1177d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 1178d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1179d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remote_ssrc = ssrc; 1180d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 1181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1182d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 1183257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 1184b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 1185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 1186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 1187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 1188d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 1189d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 1190d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 1191b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1192d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 1193b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1194b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1195b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1196d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 119782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec); 1198b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1199b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 120082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 120182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org uint32 rtx_ssrc; 120282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 120382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 120482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = 120582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org config->rtp.rtx[recv_codecs_[i].codec.id]; 120682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.ssrc = rtx_ssrc; 120782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.payload_type = recv_codecs_[i].rtx_payload_type; 120882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 120982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 1210b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1211b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1212b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { 1213b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 1214b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1215afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 1216afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return false; 1217b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1218b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1219575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1220d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator stream = 1221b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 1222b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 1223b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 1224b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1225b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1226d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström DeleteReceiveStream(stream->second); 1227b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 1228b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1229b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1230b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1231b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1232b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 1233b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 1234b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 1235b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1236afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_unsignalled_ssrc_handler_.SetDefaultRenderer(this, renderer); 1237d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1238b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1239b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1240575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1241d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1242d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1243d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1244d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return false; 1245b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1246b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1247b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1248b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1249b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1250b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1251b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { 1252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1253afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org *renderer = default_unsignalled_ssrc_handler_.GetDefaultRenderer(); 1254afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return *renderer != NULL; 1255b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1256b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1257575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1258d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1259d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1260d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1261b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1262b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1263b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1264b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1265b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1266b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1267058b1f17ac43b1fe69a8c18aaa7999ba88733dfdpbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(VideoMediaInfo* info) { 1268e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info->Clear(); 1269e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillSenderStats(info); 1270e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillReceiverStats(info); 12712b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org webrtc::Call::Stats stats = call_->GetStats(); 12722b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org FillBandwidthEstimationStats(stats, info); 12732b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org if (stats.rtt_ms != -1) { 12742b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org for (size_t i = 0; i < info->senders.size(); ++i) { 12752b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org info->senders[i].rtt_ms = stats.rtt_ms; 12762b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 12772b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 1278b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1279b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1280b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1281e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 1282575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1283e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1284e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org send_streams_.begin(); 1285e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != send_streams_.end(); 1286e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1287e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 1288e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1289e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1290e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1291e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 1292575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1293e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1294e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org receive_streams_.begin(); 1295e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != receive_streams_.end(); 1296e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1297e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 1298e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1299e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1300e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1301e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 13022b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org const webrtc::Call::Stats& stats, 1303e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoMediaInfo* video_media_info) { 13040bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo bwe_info; 13050bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_send_bandwidth = stats.send_bandwidth_bps; 13060bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_recv_bandwidth = stats.recv_bandwidth_bps; 13070bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.bucket_delay = stats.pacer_delay_ms; 13080bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 13090bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org // Get send stream bitrate stats. 13100bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 13110bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator stream = 13120bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org send_streams_.begin(); 13130bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stream != send_streams_.end(); 13140bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org ++stream) { 13150bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stream->second->FillBandwidthEstimationInfo(&bwe_info); 13160bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 13170bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org video_media_info->bw_estimations.push_back(bwe_info); 1318e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1319e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 1321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 1323d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(ssrc != 0); 1324e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1325e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope stream_lock(&stream_crit_); 1326e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (send_streams_.find(ssrc) == send_streams_.end()) { 1327e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1328e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return false; 1329e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 1330e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (!send_streams_[ssrc]->SetCapturer(capturer)) { 1331e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return false; 1332e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 133364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 133464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 133564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (capturer) { 133664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh capturer->SetApplyRotation( 133764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh !FindHeaderExtension(send_rtp_extensions_, 133864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh kRtpVideoRotationHeaderExtension)); 133964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 1340e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1341e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope lock(&capturer_crit_); 1342e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström capturers_[ssrc] = capturer; 1343e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 134464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return true; 1345b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1360d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1361d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 13624e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 136323fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg call_->Receiver()->DeliverPacket(webrtc::MediaType::VIDEO, 1364eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->size()); 13654e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 13664e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 13674e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 13684e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 13694e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 13704e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 13714e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1374b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = 0; 1375eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc)) { 1376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1379d10a68e7974a29b26d6c926e6f137255f3c173benoahric int payload_type = 0; 1380d10a68e7974a29b26d6c926e6f137255f3c173benoahric if (!GetRtpPayloadType(packet->data(), packet->size(), &payload_type)) { 1381d10a68e7974a29b26d6c926e6f137255f3c173benoahric return; 1382d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1383d10a68e7974a29b26d6c926e6f137255f3c173benoahric 1384d10a68e7974a29b26d6c926e6f137255f3c173benoahric // See if this payload_type is registered as one that usually gets its own 1385d10a68e7974a29b26d6c926e6f137255f3c173benoahric // SSRC (RTX) or at least is safe to drop either way (ULPFEC). If it is, and 1386d10a68e7974a29b26d6c926e6f137255f3c173benoahric // it wasn't handled above by DeliverPacket, that means we don't know what 1387d10a68e7974a29b26d6c926e6f137255f3c173benoahric // stream it associates with, and we shouldn't ever create an implicit channel 1388d10a68e7974a29b26d6c926e6f137255f3c173benoahric // for these. 1389d10a68e7974a29b26d6c926e6f137255f3c173benoahric for (auto& codec : recv_codecs_) { 1390d10a68e7974a29b26d6c926e6f137255f3c173benoahric if (payload_type == codec.rtx_payload_type || 1391d10a68e7974a29b26d6c926e6f137255f3c173benoahric payload_type == codec.fec.red_rtx_payload_type || 1392d10a68e7974a29b26d6c926e6f137255f3c173benoahric payload_type == codec.fec.ulpfec_payload_type) { 1393d10a68e7974a29b26d6c926e6f137255f3c173benoahric return; 1394d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1395d10a68e7974a29b26d6c926e6f137255f3c173benoahric } 1396d10a68e7974a29b26d6c926e6f137255f3c173benoahric 1397afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 1398afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDropPacket: 1399afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return; 1400afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDeliverPacket: 1401afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org break; 1402afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 1403b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 140423fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg if (call_->Receiver()->DeliverPacket(webrtc::MediaType::VIDEO, 1405eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->size()) != 14061e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1407afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; 1408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1409b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1413d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1414d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 141523fba1ffa0079f70744a83bcf4e85501dc226013Fredrik Solenberg if (call_->Receiver()->DeliverPacket(webrtc::MediaType::VIDEO, 1416eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->size()) != 14171e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1418b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTCP packet."; 1419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 142326c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); 1424cd6702282a49448adda470934f4bd9e6181cab22Jelena Marusic call_->SignalNetworkState(ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); 1425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { 1428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 1430d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(ssrc != 0); 1431575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1436ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org 1437ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org send_streams_[ssrc]->MuteStream(mute); 1438ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org return true; 1439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 144350fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvRtpHeaderExtensions"); 1444587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " 1445587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 14463c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 14473c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1448d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1449c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::vector<webrtc::RtpExtension> filtered_extensions = 1450c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org FilterRtpExtensions(extensions); 1451c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (!RtpExtensionsHaveChanged(recv_rtp_extensions_, filtered_extensions)) 1452c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1453c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1454c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org recv_rtp_extensions_ = filtered_extensions; 1455c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1456575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1457d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1458d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 1459d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 1460d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1461d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 1462d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1466b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 146850fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendRtpHeaderExtensions"); 1469587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " 1470587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 14713c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 14723c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 14733c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1474c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::vector<webrtc::RtpExtension> filtered_extensions = 1475c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org FilterRtpExtensions(extensions); 1476c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (!RtpExtensionsHaveChanged(send_rtp_extensions_, filtered_extensions)) 1477c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1478c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1479c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org send_rtp_extensions_ = filtered_extensions; 1480a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 148164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const webrtc::RtpExtension* cvo_extension = FindHeaderExtension( 148264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh send_rtp_extensions_, kRtpVideoRotationHeaderExtension); 148364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 1484575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1485d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1486d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 1487d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 1488d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1489d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 149064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh it->second->SetApplyRotation(!cvo_extension); 1491d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1495dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// Counter-intuitively this method doesn't only set global bitrate caps but also 1496dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// per-stream codec max bitrates. This is to permit SetMaxSendBitrate (b=AS) to 1497dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström// raise bitrates above the 2000k default bitrate cap. 1498008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int max_bitrate_bps) { 1499dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // TODO(pbos): Figure out whether b=AS means max bitrate for this 1500dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // WebRtcVideoChannel2 (in which case we're good), or per sender (SSRC), in 1501dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // which case this should not set a Call::BitrateConfig but rather reconfigure 1502dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // all senders. 1503008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org LOG(LS_INFO) << "SetMaxSendBandwidth: " << max_bitrate_bps << "bps."; 1504dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (max_bitrate_bps == bitrate_config_.max_bitrate_bps) 1505dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return true; 1506dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 1507008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (max_bitrate_bps <= 0) { 1508008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Unsetting max bitrate. 1509008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org max_bitrate_bps = -1; 1510008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1511008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 1512008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = max_bitrate_bps; 1513008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (max_bitrate_bps > 0 && 1514008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps > max_bitrate_bps) { 1515008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = max_bitrate_bps; 1516008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1517008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 1518dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström rtc::CritScope stream_lock(&stream_crit_); 1519dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström for (auto& kv : send_streams_) 1520dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström kv.second->SetMaxBitrateBps(max_bitrate_bps); 1521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1522b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1523b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 152550fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetOptions"); 1526a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetOptions: " << options.ToString(); 1527a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoOptions old_options = options_; 1528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 1529a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (options_ == old_options) { 1530a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // No new options to set. 1531a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 1532a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1533e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström { 1534e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope lock(&capturer_crit_); 1535e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström options_.cpu_overuse_detection.Get(&signal_cpu_adaptation_); 1536e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 1537d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org rtc::DiffServCodePoint dscp = options_.dscp.GetWithDefaultIfUnset(false) 1538d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org ? rtc::DSCP_AF41 1539d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org : rtc::DSCP_DEFAULT; 1540d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org MediaChannel::SetDscp(dscp); 1541575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 15425301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 15435301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_streams_.begin(); 15445301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it != send_streams_.end(); 15455301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ++it) { 15465301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it->second->SetOptions(options_); 15475301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1554b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1555d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Socket::OPT_RCVBUF, 1556b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1557b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1558ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // Speculative change to increase the outbound socket buffer size. 1559ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // In b/15152257, we are seeing a significant number of packets discarded 1560ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // due to lack of socket buffer space, although it's not yet clear what the 1561ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // ideal value should be. 1562ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1563ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org rtc::Socket::OPT_SNDBUF, 1564ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org kVideoRtpBufferSize); 1565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1566b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1571d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(rtc::Message* msg) { 1572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 157542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoChannel2::OnLoadUpdate(Load load) { 1576e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // OnLoadUpdate can not take any locks that are held while creating streams 1577e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // etc. Doing so establishes lock-order inversions between the webrtc process 1578e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström // thread on stream creation and locks such as stream_crit_ while calling out. 1579e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström rtc::CritScope stream_lock(&capturer_crit_); 1580e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström if (!signal_cpu_adaptation_) 1581e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström return; 1582efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng // Do not adapt resolution for screen content as this will likely result in 1583efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng // blurry and unreadable text. 1584e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström for (auto& kv : capturers_) { 1585efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng if (kv.second != nullptr 1586efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng && !kv.second->IsScreencast() 1587efbde3775b5eed8015d7e2e86ddcea3e6033d321Erik SprĂ¥ng && kv.second->video_adapter() != nullptr) { 1588e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström kv.second->video_adapter()->OnCpuResolutionRequest( 1589e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström load == kOveruse ? CoordinatedVideoAdapter::DOWNGRADE 1590e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström : CoordinatedVideoAdapter::UPGRADE); 1591e7b221f4760af10e29cb4c501e758cc3518f628bPeter Boström } 159242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org } 159342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 159442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 1595b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { 1596d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendPacket(&packet); 1598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1599b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1600b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1601d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1602b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendRtcp(&packet); 1603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1605b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1606575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1616575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1618b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 16256ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 16266ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 16276ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 16286ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 1629dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 16305301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings) 1631dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström : config(config), 1632dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström options(options), 1633dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps(max_bitrate_bps), 1634dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström codec_settings(codec_settings) { 16356ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org} 16366ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 16374d71edef45afa38b3f68b6af0519ac0f21d327dfPeter BoströmWebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( 16384d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström webrtc::VideoEncoder* encoder, 16394d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström webrtc::VideoCodecType type, 16404d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström bool external) 16414d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström : encoder(encoder), 16424d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder(nullptr), 16434d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström type(type), 16444d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external(external) { 16454d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström if (external) { 16464d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder = encoder; 16474d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström this->encoder = 16484d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström new webrtc::VideoEncoderSoftwareFallbackWrapper(type, encoder); 16494d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström } 16504d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström} 16514d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström 1652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1653b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 16547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 16556ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 1656dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps, 16575301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings, 16585301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const StreamParams& sp, 16595301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) 16607c027b64ae53a29bc528b4241cc540694c239304Henrik Kjellander : ssrcs_(sp.ssrcs), 1661259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrc_groups_(sp.ssrc_groups), 16627c027b64ae53a29bc528b4241cc540694c239304Henrik Kjellander call_(call), 16637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 1664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 1665dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström parameters_(webrtc::VideoSendStream::Config(), 1666dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström options, 1667dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström max_bitrate_bps, 1668dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström codec_settings), 16697fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_(NULL, webrtc::kVideoCodecUnknown, false), 1670b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org capturer_(NULL), 1671b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 16729a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org muted_(false), 16739a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org old_adapt_changes_(0) { 16745301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 16755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 16765301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 16775301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 16785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 16795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 16805301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 16815301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 16825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings params; 16835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (codec_settings.Get(¶ms)) { 16845301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodec(params); 16855301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1688b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 16905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 16915301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org call_->DestroyVideoSendStream(stream_); 16925301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 16937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 1694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 16964765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezstatic void CreateBlackFrame(webrtc::VideoFrame* video_frame, 1697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1699b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->CreateEmptyFrame(width, height, width, (width + 1) / 2, 1700b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org (width + 1) / 2); 1701b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 16, 1702b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1703b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 128, 1704b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1705b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 128, 1706b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1709b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1711b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 171286196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::InputFrame"); 17134765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez webrtc::VideoFrame video_frame(frame->GetVideoFrameBuffer(), 0, 0, 17144765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez frame->GetVideoRotation()); 1715d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 17165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ == NULL) { 1717ad1f9b61a3107ca27ee023990dc576abc38f05acPeter Boström // Frame input before send codecs are configured, dropping frame. 17185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org return; 17195301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 172086196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 172186196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // Not sending, abort early to prevent expensive reconfigurations while 172286196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // setting up codecs etc. 172386196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (!sending_) 172486196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org return; 172586196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 1726b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 1727d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(format_.height == 0); 1728b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1729b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1730b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1731d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org if (muted_) { 1732d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org // Create a black frame to transmit instead. 1733afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org CreateBlackFrame(&video_frame, 1734d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetWidth()), 1735d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetHeight())); 1736d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org } 1737b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1738c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions( 1739afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org video_frame.width(), video_frame.height(), capturer->IsScreencast()); 1740c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1741e433c0ef31297d78336d99cc18cf063b1a486cf2Alex Glaznev LOG(LS_VERBOSE) << "IncomingCapturedFrame: " << video_frame.width() << "x" 1742e433c0ef31297d78336d99cc18cf063b1a486cf2Alex Glaznev << video_frame.height() << " -> (codec) " 1743e433c0ef31297d78336d99cc18cf063b1a486cf2Alex Glaznev << parameters_.encoder_config.streams.back().width << "x" 1744e433c0ef31297d78336d99cc18cf063b1a486cf2Alex Glaznev << parameters_.encoder_config.streams.back().height; 1745af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(video_frame); 1746b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1747b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1748b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1749b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1750b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetCapturer"); 1751b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1752b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1753b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1754b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1755b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1756d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1757b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 17589359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (capturer == NULL) { 17599359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (stream_ != NULL) { 17609359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 17614765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez webrtc::VideoFrame black_frame; 17629359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org 1763b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org CreateBlackFrame(&black_frame, last_dimensions_.width, 1764b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org last_dimensions_.height); 1765af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(black_frame); 17669359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org } 1767b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1768b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1769b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1770b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1771b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1772b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1773b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1775b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1776b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1777b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1778b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1779b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1780b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1781b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1782b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1783b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1784b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1785b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1786b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1787b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1788b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1789d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1790b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1791b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1792b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 17936ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1794b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1795b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 1796bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.streams.back().max_framerate = 1797b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1798c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions(format.width, format.height, false); 1799b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1800b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1801b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1802b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1805ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1806d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1811963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org cricket::VideoCapturer* capturer; 1812963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org { 1813963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org rtc::CritScope cs(&lock_); 18149a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ == NULL) 1815963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org return false; 18169a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 18179a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) 18189a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org old_adapt_changes_ += capturer_->video_adapter()->adaptation_changes(); 18199a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 1820963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer = capturer_; 1821963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer_ = NULL; 1822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1823963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer->SignalVideoFrame.disconnect(this); 1824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1827d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmconst std::vector<uint32>& 1828d6f4c25eedcfd502920f1b2a24744badd9da80bePeter BoströmWebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { 1829d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return ssrcs_; 1830d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 1831d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 183264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shiehvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetApplyRotation( 183364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh bool apply_rotation) { 183464c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh rtc::CritScope cs(&lock_); 183564c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (capturer_ == NULL) 183664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return; 183764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 183864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh capturer_->SetApplyRotation(apply_rotation); 183964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh} 184064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 18415301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 18425301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1843d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 18445301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings codec_settings; 18455301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (parameters_.codec_settings.Get(&codec_settings)) { 18465301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, options); 18475301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } else { 18485301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.options = options; 18495301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 18505301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 18517fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 1852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 18535301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings) { 1854d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 18555301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 18565301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 18577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgwebrtc::VideoCodecType CodecTypeFromName(const std::string& name) { 1859e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (CodecNamesEq(name, kVp8CodecName)) { 18607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecVP8; 1861e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } else if (CodecNamesEq(name, kVp9CodecName)) { 1862188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return webrtc::kVideoCodecVP9; 1863e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } else if (CodecNamesEq(name, kH264CodecName)) { 18647fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecH264; 18657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 18667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecUnknown; 18677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 18687fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18697fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder 18707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( 18717fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const VideoCodec& codec) { 18727fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 18737fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18747fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Do not re-create encoders of the same type. 18757fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { 18767fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return allocated_encoder_; 18777fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 18787fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18797fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ != NULL) { 18807fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder* encoder = 18817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->CreateVideoEncoder(type); 18827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder != NULL) { 18837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(encoder, type, true); 18847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 18857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 18867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 18887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder( 18897fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8), type, false); 1890188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } else if (type == webrtc::kVideoCodecVP9) { 1891188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return AllocatedEncoder( 1892188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp9), type, false); 189371f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } else if (type == webrtc::kVideoCodecH264) { 189471f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin return AllocatedEncoder( 189571f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kH264), type, false); 18967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 18977fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 18987fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 18997fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // support. 1900d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(false); 19017fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(NULL, webrtc::kVideoCodecUnknown, false); 19027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 19037fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19047fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( 19057fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder* encoder) { 19067fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder->external) { 19074d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); 19087fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 19094d71edef45afa38b3f68b6af0519ac0f21d327dfPeter Boström delete encoder->encoder; 19107fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 19117fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 19125301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 19135301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings, 19145301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1915a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org parameters_.encoder_config = 1916a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 191786196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (parameters_.encoder_config.streams.empty()) 1918b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1919a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 19205301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 19215301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec.height, 1922b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 1923b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 19246ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 19257fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); 19267fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org parameters_.config.encoder_settings.encoder = new_encoder.encoder; 19275301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 19285301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 19295301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 19305301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 19315301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org // Set RTX payload type if RTX is enabled. 19325301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 1933b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (codec_settings.rtx_payload_type == -1) { 1934b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 1935b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type. Ignoring."; 1936b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.ssrcs.clear(); 1937b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } else { 1938b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 1939b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 19405301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 19415301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 194267c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström parameters_.config.rtp.nack.rtp_history_ms = 194367c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström HasNack(codec_settings.codec) ? kNackHistoryMs : 0; 19445301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 19455ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options.suspend_below_min_bitrate.Get( 19465ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org ¶meters_.config.suspend_below_min_bitrate); 19475ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org 19485301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.codec_settings.Set(codec_settings); 19496ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 1950543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1951b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 19527fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (allocated_encoder_.encoder != new_encoder.encoder) { 19537fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 19547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_ = new_encoder; 19557fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1956b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1957b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1958d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 1959d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 1960d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1961d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 19623c3f6460646183914629e5dab8ae5fcede4f0e80Peter Boström if (stream_ != nullptr) 19633c3f6460646183914629e5dab8ae5fcede4f0e80Peter Boström RecreateWebRtcStream(); 1964d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1965d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1966a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgwebrtc::VideoEncoderConfig 1967a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( 1968a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const Dimensions& dimensions, 1969a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const VideoCodec& codec) const { 1970a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config; 1971a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (dimensions.is_screencast) { 1972a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int screencast_min_bitrate_kbps; 1973a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org parameters_.options.screencast_min_bitrate.Get( 1974a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org &screencast_min_bitrate_kbps); 1975a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 1976a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org screencast_min_bitrate_kbps * 1000; 1977143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_config.content_type = 1978143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng webrtc::VideoEncoderConfig::ContentType::kScreen; 1979a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } else { 1980a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 0; 1981143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_config.content_type = 1982143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo; 1983a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1984a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1985a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Restrict dimensions according to codec max. 1986a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int width = dimensions.width; 1987a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int height = dimensions.height; 1988a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (!dimensions.is_screencast) { 1989a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.width < width) 1990a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org width = codec.width; 1991a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.height < height) 1992a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org height = codec.height; 1993a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1994a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1995a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoCodec clamped_codec = codec; 1996a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.width = width; 1997a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.height = height; 1998a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1999f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_config.streams = CreateVideoStreams( 2000dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström clamped_codec, parameters_.options, parameters_.max_bitrate_bps, 2001143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng dimensions.is_screencast ? 1 : parameters_.config.rtp.ssrcs.size()); 2002a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2003a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Conference mode screencast uses 2 temporal layers split at 100kbit. 2004a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (parameters_.options.conference_mode.GetWithDefaultIfUnset(false) && 2005a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org dimensions.is_screencast && encoder_config.streams.size() == 1) { 200646d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault(); 200746d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org 200846d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // For screenshare in conference mode, tl0 and tl1 bitrates are piggybacked 200946d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // on the VideoCodec struct as target and max bitrates, respectively. 201046d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // See eg. webrtc::VP8EncoderImpl::SetRates(). 201146d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].target_bitrate_bps = 201246d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000; 201346d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].max_bitrate_bps = config.tl1_bitrate_kbps * 1000; 2014a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.clear(); 2015a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.push_back( 201646d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000); 2017a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 2018a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return encoder_config; 2019a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 2020a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2021c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( 2022c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int width, 2023c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int height, 2024efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org bool is_screencast) { 2025efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org if (last_dimensions_.width == width && last_dimensions_.height == height && 2026efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast == is_screencast) { 2027efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org // Configured using the same parameters, do not reconfigure. 2028efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org return; 2029efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org } 2030a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetDimensions: " << width << "x" << height 2031a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org << (is_screencast ? " (screencast)" : " (not screencast)"); 2032efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 2033efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.width = width; 2034efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.height = height; 2035efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast = is_screencast; 2036efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 2037d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!parameters_.encoder_config.streams.empty()); 2038c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 2039c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org VideoCodecSettings codec_settings; 2040c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 2041c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 2042a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config = 2043a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 2044a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2045143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng encoder_config.encoder_specific_settings = ConfigureVideoEncoderSettings( 2046143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng codec_settings.codec, parameters_.options, is_screencast); 20476f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2048bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); 2049bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 2050bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = NULL; 20516f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 20526f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (!stream_reconfigured) { 2053b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 2054b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 2055b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 2056b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2057cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org 2058bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config = encoder_config; 2059b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2060b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2061b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 2062d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 2063d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(stream_ != NULL); 2064b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 2065b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 2066b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2067b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2068b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 2069d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 20705301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 20715301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org stream_->Stop(); 20725301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 2073b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 2074b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2075b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2076e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoSenderInfo 2077e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 2078e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoSenderInfo info; 207977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org webrtc::VideoSendStream::Stats stats; 208077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org { 208177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org rtc::CritScope cs(&lock_); 208277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (uint32_t ssrc : parameters_.config.rtp.ssrcs) 208377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.add_ssrc(ssrc); 208477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 208574d9ed7d853677d297807021436467a4f97584acPeter Boström VideoCodecSettings codec_settings; 208674d9ed7d853677d297807021436467a4f97584acPeter Boström if (parameters_.codec_settings.Get(&codec_settings)) 208774d9ed7d853677d297807021436467a4f97584acPeter Boström info.codec_name = codec_settings.codec.name; 208877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (size_t i = 0; i < parameters_.encoder_config.streams.size(); ++i) { 208977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (i == parameters_.encoder_config.streams.size() - 1) { 209077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 209177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].max_bitrate_bps; 209277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } else { 209377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 209477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].target_bitrate_bps; 209577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 209677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 2097e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 209877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (stream_ == NULL) 209977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org return info; 2100c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org 210177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org stats = stream_->GetStats(); 210277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 21039a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes = old_adapt_changes_; 21049a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = CoordinatedVideoAdapter::ADAPTREASON_NONE; 21059a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 21069a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ != NULL) { 21079a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (!capturer_->IsMuted()) { 21089a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org VideoFormat last_captured_frame_format; 21099a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, &info.effects_frame_drops, 21109a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &info.capturer_frame_time, 21119a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &last_captured_frame_format); 21129a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 21139a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 21149a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 21159a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) { 21169a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes += capturer_->video_adapter()->adaptation_changes(); 21179a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = capturer_->video_adapter()->adapt_reason(); 21189a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 211977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 212077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 2121259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström info.ssrc_groups = ssrc_groups_; 2122e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_input = stats.input_frame_rate; 2123e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 21243e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.avg_encode_ms = stats.avg_encode_time_ms; 21253e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.encode_usage_percent = stats.encode_usage_percent; 2126e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 212777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.nominal_bitrate = stats.media_bitrate_bps; 212877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 2129273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_width = 0; 2130273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_height = 0; 213109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 2132e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.substreams.begin(); 213309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 2134e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 213509c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats stream_stats = it->second; 2136cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_sent += stream_stats.rtp_stats.transmitted.payload_bytes + 2137cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.header_bytes + 2138cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.padding_bytes; 2139cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_sent += stream_stats.rtp_stats.transmitted.packets; 2140e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 214109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.width > info.send_frame_width) 214209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_width = stream_stats.width; 214309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.height > info.send_frame_height) 214409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_height = stream_stats.height; 21451d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_rcvd += stream_stats.rtcp_packet_type_counts.fir_packets; 21461d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_rcvd += stream_stats.rtcp_packet_type_counts.nack_packets; 21471d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_rcvd += stream_stats.rtcp_packet_type_counts.pli_packets; 2148e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 2149e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2150e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (!stats.substreams.empty()) { 2151e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 215209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats first_stream_stats = 215309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org stats.substreams.begin()->second; 2154e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.fraction_lost = 2155e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 2156e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org (1 << 8); 2157e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 2158e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2159e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 2160e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 2161e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 21620bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo( 21630bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo* bwe_info) { 21640bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope cs(&lock_); 21650bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org if (stream_ == NULL) { 21660bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org return; 21670bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 21680bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 216909c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 21700bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stats.substreams.begin(); 217109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 21720bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->transmit_bitrate += it->second.total_bitrate_bps; 21730bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps; 21740bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 2175891d48393e5ccd2f5e03d509c544c00a3d88cbbcpbos@webrtc.org bwe_info->target_enc_bitrate += stats.target_media_bitrate_bps; 217677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org bwe_info->actual_enc_bitrate += stats.media_bitrate_bps; 21770bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org} 21780bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 2179dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boströmvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetMaxBitrateBps( 2180dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int max_bitrate_bps) { 2181dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström rtc::CritScope cs(&lock_); 2182dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström parameters_.max_bitrate_bps = max_bitrate_bps; 2183dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 2184dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // No need to reconfigure if the stream hasn't been configured yet. 2185dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström if (parameters_.encoder_config.streams.empty()) 2186dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström return; 2187dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström 2188dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström // Force a stream reconfigure to set the new max bitrate. 2189dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström int width = last_dimensions_.width; 2190dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström last_dimensions_.width = 0; 2191dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström SetDimensions(width, last_dimensions_.height, last_dimensions_.is_screencast); 2192dfd53fe26b013d0948024a38eec6fbc31c29a094Peter Boström} 219342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 2194b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 2195b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 2196b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 2197b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 21986ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 21996f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 22006f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 2201bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = 2202143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng ConfigureVideoEncoderSettings( 2203143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng codec_settings.codec, parameters_.options, 2204143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng parameters_.encoder_config.content_type == 2205143cec1cc68b9ba44f3ef4467f1422704f2395f0Erik SprĂ¥ng webrtc::VideoEncoderConfig::ContentType::kScreen); 2206bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 2207b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoSendStream::Config config = parameters_.config; 2208b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { 2209b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 2210b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type the set codec. Ignoring RTX."; 2211b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org config.rtp.rtx.ssrcs.clear(); 2212b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 2213b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org stream_ = call_->CreateVideoSendStream(config, parameters_.encoder_config); 22146f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2215bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = NULL; 22166f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2217b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 2218b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 2219b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2220b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2221b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2222d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 2223d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::Call* call, 2224259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström const StreamParams& sp, 2225776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory, 2226a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream, 2227d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::VideoReceiveStream::Config& config, 2228d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) 2229d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org : call_(call), 2230259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrcs_(sp.ssrcs), 2231259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström ssrc_groups_(sp.ssrc_groups), 2232d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_(NULL), 2233a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org default_stream_(default_stream), 2234b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org config_(config), 2235776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_(external_decoder_factory), 2236b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org renderer_(NULL), 2237d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_(-1), 2238fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org last_height_(-1), 2239fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_(-1), 2240fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_(0) { 2241d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.renderer = this; 2242d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 2243d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRecvCodecs(recv_codecs); 2244d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2245d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 22467252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter BoströmWebRtcVideoChannel2::WebRtcVideoReceiveStream::AllocatedDecoder:: 22477252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström AllocatedDecoder(webrtc::VideoDecoder* decoder, 22487252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström webrtc::VideoCodecType type, 22497252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström bool external) 22507252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström : decoder(decoder), 22517252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external_decoder(nullptr), 22527252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström type(type), 22537252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external(external) { 22547252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström if (external) { 22557252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström external_decoder = decoder; 22567252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström this->decoder = 22577252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström new webrtc::VideoDecoderSoftwareFallbackWrapper(type, external_decoder); 22587252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström } 22597252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström} 22607252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström 2261d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 2262d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 226396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org ClearDecoders(&allocated_decoders_); 2264d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2265d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2266d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boströmconst std::vector<uint32>& 2267d6f4c25eedcfd502920f1b2a24744badd9da80bePeter BoströmWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetSsrcs() const { 2268d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström return ssrcs_; 2269d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström} 2270d6f4c25eedcfd502920f1b2a24744badd9da80bePeter Boström 227196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::AllocatedDecoder 227296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder( 227396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* old_decoders, 227496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodec& codec) { 227596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 2276776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 227796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < old_decoders->size(); ++i) { 227896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*old_decoders)[i].type == type) { 227996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder decoder = (*old_decoders)[i]; 228096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org (*old_decoders)[i] = old_decoders->back(); 228196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org old_decoders->pop_back(); 228296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return decoder; 228396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 228496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2285776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 228696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_decoder_factory_ != NULL) { 228796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder* decoder = 228896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_decoder_factory_->CreateVideoDecoder(type); 228996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (decoder != NULL) { 229096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(decoder, type, true); 229196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 229296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2293776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 229496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 229596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder( 229696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp8), type, false); 229796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 2298d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2299b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (type == webrtc::kVideoCodecVP9) { 2300b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org return AllocatedDecoder( 2301b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp9), type, false); 2302b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 2303b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org 230471f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin if (type == webrtc::kVideoCodecH264) { 230571f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin return AllocatedDecoder( 230671f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kH264), type, false); 230771f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin } 230871f6f4405c1c5f60097f8d10841378088e78e8b9Zeke Chin 230996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 231096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // support. 2311d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(false); 231296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(NULL, webrtc::kVideoCodecUnknown, false); 231396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 231496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 231596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 231696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 231796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder> old_decoders = allocated_decoders_; 231896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.clear(); 231996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.clear(); 232096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < recv_codecs.size(); ++i) { 232196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder allocated_decoder = 232296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CreateOrReuseVideoDecoder(&old_decoders, recv_codecs[i].codec); 232396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.push_back(allocated_decoder); 2324d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 232596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoReceiveStream::Decoder decoder; 232696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.decoder = allocated_decoder.decoder; 232796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_type = recv_codecs[i].codec.id; 232896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_name = recv_codecs[i].codec.name; 232996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.push_back(decoder); 233096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 233196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 233296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 233396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 2334257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.nack.rtp_history_ms = 2335e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin HasNack(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 2336257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 233796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org ClearDecoders(&old_decoders); 2338d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 2339d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2340d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 23413548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boströmvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetLocalSsrc( 23423548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström uint32_t local_ssrc) { 23433548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström // TODO(pbos): Consider turning this sanity check into a DCHECK. You should 23443548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström // not be able to create a sender with the same SSRC as a receiver, but right 23453548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström // now this can't be done due to unittests depending on receiving what they 23463548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström // are sending from the same MediaChannel. 23473548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström if (local_ssrc == config_.rtp.remote_ssrc) 23483548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström return; 23493548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström 23503548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström config_.rtp.local_ssrc = local_ssrc; 23513548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström RecreateWebRtcStream(); 23523548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström} 23533548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström 235467c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boströmvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetNackAndRemb( 235567c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström bool nack_enabled, bool remb_enabled) { 235667c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström int nack_history_ms = nack_enabled ? kNackHistoryMs : 0; 235767c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström if (config_.rtp.nack.rtp_history_ms == nack_history_ms && 235867c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström config_.rtp.remb == remb_enabled) { 2359126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström return; 236067c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström } 236167c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström config_.rtp.remb = remb_enabled; 236267c9df79828991c5aab96b9253ae4e7ba7ed508ePeter Boström config_.rtp.nack.rtp_history_ms = nack_history_ms; 2363126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström RecreateWebRtcStream(); 2364126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström} 2365126c03ea02d8a99bfa3d1e6d6fe04516183d31afPeter Boström 2366d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 2367d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 2368d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.extensions = extensions; 23693548dd21542c7b3f2c4680c6a6d86b0d719bd008Peter Boström RecreateWebRtcStream(); 2370d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2371d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2372d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 2373d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (stream_ != NULL) { 2374d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 2375d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2376d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 2377d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_->Start(); 2378d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2379d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 238096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( 238196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* allocated_decoders) { 238296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < allocated_decoders->size(); ++i) { 238396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*allocated_decoders)[i].external) { 2384776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_->DestroyVideoDecoder( 23857252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström (*allocated_decoders)[i].external_decoder); 2386776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 23877252a2ba8035c4128917a9558a3e34fc9dbe7c44Peter Boström delete (*allocated_decoders)[i].decoder; 2388776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 238996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders->clear(); 2390776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org} 2391776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 2392d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 23934765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez const webrtc::VideoFrame& frame, 2394d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int time_to_render_ms) { 2395d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2396fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 2397fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (first_frame_timestamp_ < 0) 2398fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_ = frame.timestamp(); 2399fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t rtp_time_elapsed_since_first_frame = 2400fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (timestamp_wraparound_handler_.Unwrap(frame.timestamp()) - 2401fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_); 2402fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t elapsed_time_ms = rtp_time_elapsed_since_first_frame / 2403fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (cricket::kVideoCodecClockrate / 1000); 2404fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (frame.ntp_time_ms() > 0) 2405fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_ = frame.ntp_time_ms() - elapsed_time_ms; 2406fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 2407d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ == NULL) { 2408d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 2409d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return; 2410d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2411d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2412d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 2413d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(frame.width(), frame.height()); 2414d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2415d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 24162386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org const WebRtcVideoFrame render_frame( 24172386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org frame.video_frame_buffer(), 24182386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org elapsed_time_ms * rtc::kNumNanosecsPerMillisec, 241964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh frame.render_time_ms() * rtc::kNumNanosecsPerMillisec, frame.rotation()); 2420d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_->RenderFrame(&render_frame); 2421d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2422d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 24230d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsTextureSupported() const { 24240d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org return true; 24250d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org} 24260d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org 2427a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsDefaultStream() const { 2428a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return default_stream_; 2429a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 2430a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 2431d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 2432d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org cricket::VideoRenderer* renderer) { 2433d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2434d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_ = renderer; 2435d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 2436d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(last_width_, last_height_); 2437d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2438d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2439d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2440d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 2441d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 2442d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // design. 2443d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2444d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return renderer_; 2445d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2446d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2447d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 2448d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int height) { 2449d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2450d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 2451d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 2452d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2453d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_ = width; 2454d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_ = height; 2455d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2456d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2457e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoReceiverInfo 2458e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 2459e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoReceiverInfo info; 2460259bd2034c3d3ee7f2dc4d481e9bf896a3a4d6efPeter Boström info.ssrc_groups = ssrc_groups_; 2461e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 2462e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 2463cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_rcvd = stats.rtp_stats.transmitted.payload_bytes + 2464cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.header_bytes + 2465cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.padding_bytes; 2466cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_rcvd = stats.rtp_stats.transmitted.packets; 2467393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström info.packets_lost = stats.rtcp_stats.cumulative_lost; 2468393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström info.fraction_lost = 2469393347ff988708df5037ddcd181fe204bd1ab37ePeter Boström static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8); 2470e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2471e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 2472e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 2473e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_output = stats.render_frame_rate; 2474e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 24751d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org { 24761d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org rtc::CritScope frame_cs(&renderer_lock_); 24771d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_width = last_width_; 24781d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_height = last_height_; 24791d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.capture_start_ntp_time_ms = estimated_remote_start_ntp_time_ms_; 24801d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org } 24811d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org 248209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.decode_ms = stats.decode_ms; 248309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.max_decode_ms = stats.max_decode_ms; 248409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.current_delay_ms = stats.current_delay_ms; 248509c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.target_delay_ms = stats.target_delay_ms; 248609c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.jitter_buffer_ms = stats.jitter_buffer_ms; 248709c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.min_playout_delay_ms = stats.min_playout_delay_ms; 248809c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.render_delay_ms = stats.render_delay_ms; 248909c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org 24901d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_sent = stats.rtcp_packet_type_counts.fir_packets; 24911d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_sent = stats.rtcp_packet_type_counts.pli_packets; 24921d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets; 2493e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2494e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 2495e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 2496e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 2498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 2499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2500a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgbool WebRtcVideoChannel2::VideoCodecSettings::operator==( 2501a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2502a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return codec == other.codec && 2503a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && 2504a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.red_payload_type == other.fec.red_payload_type && 2505e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec.red_rtx_payload_type == other.fec.red_rtx_payload_type && 2506a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org rtx_payload_type == other.rtx_payload_type; 2507a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 2508a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2509ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boströmbool WebRtcVideoChannel2::VideoCodecSettings::operator!=( 2510ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2511ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström return !(*this == other); 2512ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström} 2513ee0b00e8a9cc2d8f4578912a389dee92ac020ee9Peter Boström 2514b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 2515b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 2516d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!codecs.empty()); 2517b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2518b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 2519b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 2520e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 2521d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // |rtx_mapping| maps video payload type to rtx payload type. 2522d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org std::map<int, int> rtx_mapping; 2523b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 2525b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 2527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 2528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 2529b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2530b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 2531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 2532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 2533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 2536e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 2537b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 2539b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 2540b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 2541d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(fec_settings.red_payload_type == -1); 2542b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 2543b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2544b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2545b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2546b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 2547b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 2548d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(fec_settings.ulpfec_payload_type == -1); 2549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 2550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 2554b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 2555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 2556e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org &associated_payload_type) || 2557e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org !IsValidRtpPayloadType(associated_payload_type)) { 2558e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org LOG(LS_ERROR) 2559e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << "RTX codec with invalid or no associated payload type: " 2560e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << in_codec.ToString(); 2561b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2562b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2563b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 2564b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2566b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 2568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 2569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 2572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 2573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 2576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 2577d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(!video_codecs.empty()); 2578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2579e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 2580e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org it != rtx_mapping.end(); 2581e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org ++it) { 2582e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!payload_used[it->first]) { 2583e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 2584e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2585e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2586e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO && 2587e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin payload_codec_type[it->first] != VideoCodec::CODEC_RED) { 2588e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin LOG(LS_ERROR) << "RTX not mapped to regular video codec or RED codec."; 2589e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2590e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2591e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin 2592e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (it->first == fec_settings.red_payload_type) { 2593e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec_settings.red_rtx_payload_type = it->second; 2594e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 2595e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2596e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 2597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 2598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 2599e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (rtx_mapping[video_codecs[i].codec.id] != 0 && 2600e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin rtx_mapping[video_codecs[i].codec.id] != 2601e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin fec_settings.red_payload_type) { 2602b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2605b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2606b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 2607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 2610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 2612