webrtcvideoengine2.cc revision 3bf3d238c8c4578e444e5a601684db68c79a29ca
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 313c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org#include <set> 32b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include <string> 33b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 34b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "libyuv/convert_from.h" 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" 38b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideocapturer.h" 39b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoframe.h" 40b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvoiceengine.h" 41a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/buffer.h" 42a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/logging.h" 43a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/stringutils.h" 44b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/call.h" 45776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org#include "webrtc/video_decoder.h" 46ab990ae43a2b84b103cb3c50bc38502375c13e68pbos@webrtc.org#include "webrtc/video_encoder.h" 47b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 48b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#define UNIMPLEMENTED \ 49b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Call to unimplemented function " << __FUNCTION__; \ 50b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(false) 51b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 52b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace cricket { 537fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgnamespace { 547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 557fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic bool CodecNameMatches(const std::string& name1, 567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::string& name2) { 577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return _stricmp(name1.c_str(), name2.c_str()) == 0; 587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org// True if codec is supported by a software implementation that's always 617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org// available. 627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic bool CodecIsInternallySupported(const std::string& codec_name) { 637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return CodecNameMatches(codec_name, kVp8CodecName); 647fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { 677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::stringstream out; 687fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '{'; 697fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << codecs[i].ToString(); 717fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (i != codecs.size() - 1) { 727fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << ", "; 737fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 747fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 757fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '}'; 767fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return out.str(); 777fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 787fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 797fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic bool ValidateCodecFormats(const std::vector<VideoCodec>& codecs) { 807fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org bool has_video = false; 817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!codecs[i].ValidateCodecFormat()) { 837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return false; 847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (codecs[i].GetCodecType() == VideoCodec::CODEC_VIDEO) { 867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org has_video = true; 877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 897fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!has_video) { 907fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org LOG(LS_ERROR) << "Setting codecs without a video codec is invalid: " 917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org << CodecVectorToString(codecs); 927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return false; 937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 947fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return true; 957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 977fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic std::string RtpExtensionsToString( 987fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 997fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::stringstream out; 1007fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '{'; 1017fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; 1037fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (i != extensions.size() - 1) { 1047fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << ", "; 1057fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1067fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1077fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '}'; 1087fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return out.str(); 1097fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 1107fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 1117fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} // namespace 112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// duration hasn't been implemented. 115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 117933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.orgstatic const int kDefaultQpMax = 56; 118933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org 119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1217fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org// External video encoders are given payloads 120-127. This also means that we 1227fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org// only support up to 8 external payload types. 1237fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic const int kExternalVideoPayloadTypeBase = 120; 1247fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org#ifndef NDEBUG 1257fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic const size_t kMaxExternalVideoCodecs = 8; 1267fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org#endif 1277fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstruct VideoCodecPref { 129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type; 13097fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org int width; 13197fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org int height; 132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const char* name; 133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rtx_payload_type; 13497fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org} kDefaultVideoCodecPref = {100, 640, 400, kVp8CodecName, 96}; 135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1367fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgconst char kH264CodecName[] = "H264"; 1377fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 13897fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.orgVideoCodecPref kRedPref = {116, -1, -1, kRedCodecName, -1}; 13997fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.orgVideoCodecPref kUlpfecPref = {117, -1, -1, kUlpfecCodecName, -1}; 140b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 141b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 142b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& requested_codec, 143b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* matching_codec) { 144b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 145b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 146b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *matching_codec = codecs[i]; 147b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 148b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 149b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 150b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 151b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 152b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 153f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.orgstatic void AddDefaultFeedbackParams(VideoCodec* codec) { 154f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kFir(kRtcpFbParamCcm, kRtcpFbCcmParamFir); 155f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kFir); 156f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kNack(kRtcpFbParamNack, kParamValueEmpty); 157f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kNack); 158f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kPli(kRtcpFbParamNack, kRtcpFbNackParamPli); 159f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kPli); 160f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kRemb(kRtcpFbParamRemb, kParamValueEmpty); 161f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kRemb); 162f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org} 163f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org 164f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.orgstatic bool IsNackEnabled(const VideoCodec& codec) { 165f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org return codec.HasFeedbackParam( 166f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); 167f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org} 168f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org 169257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.orgstatic bool IsRembEnabled(const VideoCodec& codec) { 170257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org return codec.HasFeedbackParam( 171257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); 172257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org} 173257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 174b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultVideoCodec() { 175b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec default_codec(kDefaultVideoCodecPref.payload_type, 176b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.name, 17797fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org kDefaultVideoCodecPref.width, 17897fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org kDefaultVideoCodecPref.height, 179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultFramerate, 180b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 0); 181f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org AddDefaultFeedbackParams(&default_codec); 182b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return default_codec; 183b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 184b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultRedCodec() { 186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kRedPref.payload_type, kRedPref.name, 0, 0, 0, 0); 187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 188b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 189b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultUlpfecCodec() { 190b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kUlpfecPref.payload_type, kUlpfecPref.name, 0, 0, 0, 0); 191b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 192b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 193b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic std::vector<VideoCodec> DefaultVideoCodecs() { 194b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodec> codecs; 195b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultVideoCodec()); 196b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultRedCodec()); 197b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultUlpfecCodec()); 198b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (kDefaultVideoCodecPref.rtx_payload_type != -1) { 199b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back( 200b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec::CreateRtxCodec(kDefaultVideoCodecPref.rtx_payload_type, 201b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.payload_type)); 202b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 203b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return codecs; 204b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 205b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2063c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic bool ValidateRtpHeaderExtensionIds( 2073c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 2083c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::set<int> extensions_used; 2093c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 2103c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (extensions[i].id < 0 || extensions[i].id >= 15 || 2113c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org !extensions_used.insert(extensions[i].id).second) { 2123c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; 2133c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 2143c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 2153c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 2163c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return true; 2173c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 2183c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 2193c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic std::vector<webrtc::RtpExtension> FilterRtpExtensions( 2203c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 2213c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::vector<webrtc::RtpExtension> webrtc_extensions; 2223c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 2233c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org // Unsupported extensions will be ignored. 2243c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (webrtc::RtpExtension::IsSupported(extensions[i].uri)) { 2253c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org webrtc_extensions.push_back(webrtc::RtpExtension( 2263c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org extensions[i].uri, extensions[i].id)); 2273c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } else { 2283c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; 2293c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 2303c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 2313c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return webrtc_extensions; 2323c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 2333c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 2340d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.orgWebRtcVideoEncoderFactory2::~WebRtcVideoEncoderFactory2() { 2350d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org} 2360d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org 237d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgstd::vector<webrtc::VideoStream> WebRtcVideoEncoderFactory2::CreateVideoStreams( 238d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 239d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 240d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 241d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org if (num_streams != 1) { 242d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org LOG(LS_ERROR) << "Unsupported number of streams: " << num_streams; 243d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return std::vector<webrtc::VideoStream>(); 2446ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org } 245b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 246d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 247d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 248d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 249d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 250d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultFramerate; 251d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 252d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int min_bitrate = kMinVideoBitrate; 253d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMinBitrate, &min_bitrate); 254d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int max_bitrate = kMaxVideoBitrate; 255d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxBitrate, &max_bitrate); 256d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.min_bitrate_bps = min_bitrate * 1000; 257d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate * 1000; 258d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 259933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org int max_qp = kDefaultQpMax; 260d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 261d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 262d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 263d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 264d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 265d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 266b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2676f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid* WebRtcVideoEncoderFactory2::CreateVideoEncoderSettings( 2686f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 2696f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoOptions& options) { 2707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecNameMatches(codec.name, kVp8CodecName)) { 2716cd6ba8ae016200a7a13b43294b8faf5d1d4affdpbos@webrtc.org webrtc::VideoCodecVP8* settings = new webrtc::VideoCodecVP8( 2726cd6ba8ae016200a7a13b43294b8faf5d1d4affdpbos@webrtc.org webrtc::VideoEncoder::GetDefaultVp8Settings()); 2736f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org options.video_noise_reduction.Get(&settings->denoisingOn); 2746f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return settings; 2756f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2766f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 2776f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 2786f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2796f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoEncoderFactory2::DestroyVideoEncoderSettings( 2806f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 2816f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org void* encoder_settings) { 2826f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (encoder_settings == NULL) { 2836f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return; 2846f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecNameMatches(codec.name, kVp8CodecName)) { 2866f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org delete reinterpret_cast<webrtc::VideoCodecVP8*>(encoder_settings); 2876f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 288d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 289d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 290afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgDefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler() 291afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org : default_recv_ssrc_(0), default_renderer_(NULL) {} 292afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 293afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgUnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc( 294afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 295afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org uint32_t ssrc) { 296afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 297afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 298afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDropPacket; 299afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 300afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 301afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org StreamParams sp; 302afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org sp.ssrcs.push_back(ssrc); 303afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 304afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (!channel->AddRecvStream(sp)) { 305afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Could not create default receive stream."; 306afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 307afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 308afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(ssrc, default_renderer_); 309afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_recv_ssrc_ = ssrc; 310afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDeliverPacket; 311afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 312afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 31342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgWebRtcCallFactory::~WebRtcCallFactory() { 31442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 31542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgwebrtc::Call* WebRtcCallFactory::CreateCall( 31642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org const webrtc::Call::Config& config) { 31742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org return webrtc::Call::Create(config); 31842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 31942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 320afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgVideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { 321afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return default_renderer_; 322afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 323afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 324afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgvoid DefaultUnsignalledSsrcHandler::SetDefaultRenderer( 325afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 326afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoRenderer* renderer) { 327afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_renderer_ = renderer; 328afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { 329afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(default_recv_ssrc_, default_renderer_); 330afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 331afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 332afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 33397fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2() 334b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : worker_thread_(NULL), 335b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org voice_engine_(NULL), 336992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org default_codec_format_(kDefaultVideoCodecPref.width, 337992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org kDefaultVideoCodecPref.height, 338992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org FPS_TO_INTERVAL(kDefaultFramerate), 339992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org FOURCC_ANY), 340b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org initialized_(false), 341b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org cpu_monitor_(new rtc::CpuMonitor(NULL)), 34242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_factory_(&default_call_factory_), 3430a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_(NULL), 3440a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_(NULL) { 345b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; 3467fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 347587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 348587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 349587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpTimestampOffsetHeaderExtensionDefaultId)); 350587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 351587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 352587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Terminate(); 360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 36342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoEngine2::SetCallFactory(WebRtcCallFactory* call_factory) { 3647fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(!initialized_); 36542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_factory_ = call_factory; 36642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 36742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 368d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgbool WebRtcVideoEngine2::Init(rtc::Thread* worker_thread) { 369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org worker_thread_ = worker_thread; 371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(worker_thread_ != NULL); 372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->set_thread(worker_thread_); 374b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!cpu_monitor_->Start(kCpuMonitorPeriodMs)) { 375b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Failed to start CPU monitor."; 376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_.reset(); 377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 379b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::Terminate() { 384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Terminate"; 385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->Stop(); 387b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 388b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = false; 389b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 390b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 391b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgint WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } 392b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoEncoderConfig& config) { 3958fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org const VideoCodec& codec = config.max_codec; 3968fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org // TODO(pbos): Make use of external encoder factory. 3977fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!CodecIsInternallySupported(codec.name)) { 3988fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported:" 3998fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org << codec.ToString(); 4008fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return false; 4018fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 4028fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 403992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org default_codec_format_ = 404992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org VideoFormat(codec.width, 405992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org codec.height, 406992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org VideoFormat::FpsToInterval(codec.framerate), 407992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org FOURCC_ANY); 4088fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org video_codecs_.clear(); 4098fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org video_codecs_.push_back(codec); 410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoEncoderConfig WebRtcVideoEngine2::GetDefaultEncoderConfig() const { 414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoEncoderConfig(DefaultVideoCodec()); 415b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 416b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 417b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 4181ecbe45c7e4c9142896cb2810d699558518f4f28buildbot@webrtc.org const VideoOptions& options, 419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel) { 4207fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(initialized_); 421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "CreateChannel: " 422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (voice_channel != NULL ? "With" : "Without") 423fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org << " voice channel. Options: " << options.ToString(); 4247fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoChannel2* channel = 4257fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org new WebRtcVideoChannel2(call_factory_, 4263bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org voice_engine_, 4277fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org voice_channel, 428fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options, 4297fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_, 4307fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_decoder_factory_, 4317fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org GetVideoEncoderFactory()); 432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!channel->Init()) { 433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete channel; 434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 436e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org channel->SetRecvCodecs(video_codecs_); 437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return channel; 438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 444b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 445b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 446b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return rtp_header_extensions_; 447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { 450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Set up logging. 451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; 452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if min_sev == -1, we keep the current log level. 453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (min_sev < 0) { 454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(min_sev == -1); 455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 4590a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalDecoderFactory( 4600a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoDecoderFactory* decoder_factory) { 4617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(!initialized_); 4620a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_ = decoder_factory; 4630a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 4640a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 4650a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalEncoderFactory( 4660a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoEncoderFactory* encoder_factory) { 4677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(!initialized_); 4680a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_ = encoder_factory; 4697fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 4707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 4710a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 4720a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 475b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 476b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 477b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 478b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 479b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 480b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 481b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 4838fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 4848fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 4858fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (codec.Matches(in)) { 4868fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 490b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 491b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// dimensions will be used for aspect ratio matching. 496b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& current, 498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* out) { 499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(out != NULL); 500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width != requested.height && 502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 503b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // 0xn and nx0 are invalid resolutions. 504b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 505b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 506b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 507b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec matching_codec; 508b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 509b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Codec not supported. 510b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 513b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->id = requested.id; 514b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->name = requested.name; 515b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->preference = requested.preference; 516b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 517b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->framerate = 518d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::_min(requested.framerate, matching_codec.framerate); 519b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->feedback_params = requested.feedback_params; 5218fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width = requested.width; 5228fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height = requested.height; 5238fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 5248fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 5258fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 5268fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 5278fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org while (out->width > matching_codec.width) { 5288fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width /= 2; 5298fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height /= 2; 5308fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 5318fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 5328fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return out->width > 0 && out->height > 0; 533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetVoiceEngine(WebRtcVoiceEngine* voice_engine) { 536b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 537b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "SetVoiceEngine can not be called after Init"; 538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 539b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 540b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org voice_engine_ = voice_engine; 541b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 542b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 543b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 544b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 545b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 546b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 547b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 554b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 556d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgWebRtcVideoEncoderFactory2* WebRtcVideoEngine2::GetVideoEncoderFactory() { 557d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return &default_video_encoder_factory_; 558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 5607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstd::vector<VideoCodec> WebRtcVideoEngine2::GetSupportedCodecs() const { 5617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::vector<VideoCodec> supported_codecs = DefaultVideoCodecs(); 5627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ == NULL) { 5647fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 5657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 5667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(external_encoder_factory_->codecs().size() <= kMaxExternalVideoCodecs); 5687fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs = 5697fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->codecs(); 5707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 5717fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Don't add internally-supported codecs twice. 5727fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecIsInternallySupported(codecs[i].name)) { 5737fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org continue; 5747fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 5757fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5767fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org VideoCodec codec(kExternalVideoPayloadTypeBase + static_cast<int>(i), 5777fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].name, 5787fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_width, 5797fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_height, 5807fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_fps, 5817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 0); 5827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AddDefaultFeedbackParams(&codec); 5847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org supported_codecs.push_back(codec); 5857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 5867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 5877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 5887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5896ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org// Thin map between VideoFrame and an existing webrtc::I420VideoFrame 590b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// to avoid having to copy the rendered VideoFrame prematurely. 591b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This implementation is only safe to use in a const context and should never 592b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be written to. 5936ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgclass WebRtcVideoRenderFrame : public VideoFrame { 594b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org public: 595b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org explicit WebRtcVideoRenderFrame(const webrtc::I420VideoFrame* frame) 596b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : frame_(frame) {} 597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool InitToBlack(int w, 599b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 600b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 601b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 602b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) OVERRIDE { 604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 605b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 606b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool Reset(uint32 fourcc, 609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int w, 610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dw, 612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dh, 613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* sample, 614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t sample_size, 615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 618b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp, 619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rotation) OVERRIDE { 620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetWidth() const OVERRIDE { 625b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->width()); 626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 627b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetHeight() const OVERRIDE { 628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->height()); 629b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetYPlane() const OVERRIDE { 632b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kYPlane); 633b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 634b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetUPlane() const OVERRIDE { 635b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kUPlane); 636b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 637b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetVPlane() const OVERRIDE { 638b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kVPlane); 639b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 640b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 641b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetYPlane() OVERRIDE { 642b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 643b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 645b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetUPlane() OVERRIDE { 646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetVPlane() OVERRIDE { 650b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 651b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 653b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 654b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetYPitch() const OVERRIDE { 655b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kYPlane); 656b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 657b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetUPitch() const OVERRIDE { 658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kUPlane); 659b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetVPitch() const OVERRIDE { 661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kVPlane); 662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void* GetNativeHandle() const OVERRIDE { return NULL; } 665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelWidth() const OVERRIDE { return 1; } 667b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelHeight() const OVERRIDE { return 1; } 668b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 669b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetElapsedTime() const OVERRIDE { 670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert millisecond render time to ns timestamp. 671d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org return frame_->render_time_ms() * rtc::kNumNanosecsPerMillisec; 672b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 673b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetTimeStamp() const OVERRIDE { 674b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert 90K rtp timestamp to ns timestamp. 675d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org return (frame_->timestamp() / 90) * rtc::kNumNanosecsPerMillisec; 676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetElapsedTime(int64 elapsed_time) OVERRIDE { UNIMPLEMENTED; } 678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetTimeStamp(int64 time_stamp) OVERRIDE { UNIMPLEMENTED; } 679b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int GetRotation() const OVERRIDE { 681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return ROTATION_0; 683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 684b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 685b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* Copy() const OVERRIDE { 686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 688b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool MakeExclusive() OVERRIDE { 691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 693b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t CopyToBuffer(uint8* buffer, size_t size) const { 696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; 698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 699b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(fbarchard): Refactor into base class and share with LMI 701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, 702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* buffer, 703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t size, 704b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int stride_rgb) const OVERRIDE { 705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t width = GetWidth(); 706b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t height = GetHeight(); 707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t needed = (stride_rgb >= 0 ? stride_rgb : -stride_rgb) * height; 708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (size < needed) { 709b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "RGB buffer is not large enough"; 710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 711b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 712b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 713b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (libyuv::ConvertFromI420(GetYPlane(), 714b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetYPitch(), 715b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPlane(), 716b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPitch(), 717b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPlane(), 718b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPitch(), 719b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org buffer, 720b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stride_rgb, 721b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(width), 722b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(height), 723b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org to_fourcc)) { 724b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RGB type not supported: " << to_fourcc; 725b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; // 0 indicates error 726b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 727b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 728b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 729b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 730b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org protected: 731b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* CreateEmptyFrame(int w, 732b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 733b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 734b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 735b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 736b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) const OVERRIDE { 737b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoFrame* frame = new WebRtcVideoFrame(); 738b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame->InitToBlack( 739b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org w, h, pixel_width, pixel_height, elapsed_time, time_stamp); 740b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame; 741b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 742b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 743b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org private: 744b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const webrtc::I420VideoFrame* const frame_; 745b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org}; 746b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 747b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 74842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org WebRtcCallFactory* call_factory, 7493bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org WebRtcVoiceEngine* voice_engine, 750b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel, 751fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org const VideoOptions& options, 7527fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 7537fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory, 754b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 755b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 7563bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org voice_channel_(voice_channel), 7577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 7587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_decoder_factory_(external_decoder_factory), 759b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org encoder_factory_(encoder_factory) { 760fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org SetDefaultOptions(); 761fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options_.SetAll(options); 762b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call::Config config(this); 76342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org config.overuse_callback = this; 7643bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org if (voice_engine != NULL) { 7653bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org config.voice_engine = voice_engine->voe()->engine(); 7663bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org } 767fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org 768fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org // Set start bitrate for the call. A default is provided by SetDefaultOptions. 769fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org int start_bitrate_kbps; 770fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options_.video_start_bitrate.Get(&start_bitrate_kbps); 771fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org config.stream_start_bitrate_bps = start_bitrate_kbps * 1000; 772fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org 77342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_.reset(call_factory->CreateCall(config)); 774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 775b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 776b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 777b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 7786f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 7796f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 7806f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 78142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org options_.cpu_overuse_detection.Set(false); 7825ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options_.suspend_below_min_bitrate.Set(false); 78342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org options_.use_payload_padding.Set(false); 78442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org options_.video_noise_reduction.Set(true); 785fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options_.video_start_bitrate.Set( 786fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org webrtc::Call::Config::kDefaultStartBitrateBps / 1000); 787efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org options_.screencast_min_bitrate.Set(0); 788b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 789b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 790b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 791b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 792b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 793b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 794b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 795b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 796b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 797b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 798d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 799b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.begin(); 800b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != receive_streams_.end(); 801b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 802b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 805b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 806b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::Init() { return true; } 807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 811b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 812b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 813b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 814b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 815b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without video codec payloads."; 817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Add a decoder factory which controls supported codecs. 821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Blocked on webrtc:2854. 822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 8237fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!CodecNameMatches(mapped_codecs[i].codec.name, kVp8CodecName)) { 824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported codec: '" 825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << mapped_codecs[i].codec.name << "'"; 826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 827b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 829b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 830b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org recv_codecs_ = mapped_codecs; 831d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 832575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 833d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 834d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 835d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 836d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 837d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 838d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 839d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 840b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 841b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 851b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 853b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No video codecs supported by encoder factory."; 854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 855b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 856b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 857b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_codec_.Set(supported_codecs.front()); 858b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 859b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 860575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 861d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 862d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 863d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 864d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 865d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org assert(it->second != NULL); 866d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetCodec(supported_codecs.front()); 867d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 868b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 869b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 871b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 873b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodecSettings codec_settings; 874b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 875b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 876b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 877b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 878b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *codec = codec_settings.codec; 879b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, 883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 885b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 886575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRender(bool render) { 894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. 895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); 896b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 897b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 898b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send && !send_codec_.IsSet()) { 902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 905b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 907b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 908b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 909b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 910b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 911b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 912b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 913b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 914b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 915b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 916b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sp.ssrcs.empty()) { 917b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No SSRCs in stream parameters."; 918b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 919b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 920b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 921b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 922b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 923b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Make sure none of sp.ssrcs are used, not just the identifying 924b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ssrc. 925575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 926b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) != send_streams_.end()) { 927b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Send stream with ssrc '" << ssrc << "' already exists."; 928b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 929b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 930b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 9315301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> primary_ssrcs; 9325301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(&primary_ssrcs); 9335301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> rtx_ssrcs; 9345301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(primary_ssrcs, &rtx_ssrcs); 9355301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 9365301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_ERROR) 9375301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 9385301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << sp.ToString(); 939b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 940b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 941b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 942b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoSendStream* stream = 9436ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org new WebRtcVideoSendStream(call_.get(), 9447fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_, 9455301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org encoder_factory_, 9466ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options_, 9475301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_codec_, 9485301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp, 9495301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_rtp_extensions_); 9505301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 951b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 952b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 953b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 954b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 955b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 956b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 957b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 958b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 959b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 960b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 961b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 962b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 963b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 964b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 965b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 966b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { 967b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 968b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 969b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 970b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 971b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 972b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 973b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 974b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 975b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 976b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 977b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 978b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 979575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org WebRtcVideoSendStream* removed_stream; 980575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org { 981575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 982575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org std::map<uint32, WebRtcVideoSendStream*>::iterator it = 983575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.find(ssrc); 984575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org if (it == send_streams_.end()) { 985575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org return false; 986575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org } 987575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org 988575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org removed_stream = it->second; 989575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.erase(it); 990b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 991b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 992575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org delete removed_stream; 993b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 994b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 995b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 996b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 997b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 998b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 999b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1000b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1001b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 1002b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); 1003b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(sp.ssrcs.size() > 0); 1004b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1005b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 1006b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); // TODO(pbos): Is this ever valid? 1007b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1008b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Check if any of the SSRCs overlap. 1009575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1010b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (receive_streams_.find(ssrc) != receive_streams_.end()) { 1011b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Receive stream for SSRC " << ssrc << "already exists."; 1012b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1013b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1014b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1015bd249bc711b3c9efd142eb8de3df489282fe693epbos@webrtc.org webrtc::VideoReceiveStream::Config config; 1016d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ConfigureReceiverRtp(&config, sp); 10173bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 10183bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // Set up A/V sync if there is a VoiceChannel. 10193bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // TODO(pbos): The A/V is synched by the receiving channel. So we need to know 10203bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // the SSRC of the remote audio channel in order to sync the correct webrtc 10213bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // VoiceEngine channel. For now sync the first channel in non-conference to 10223bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // match existing behavior in WebRtcVideoEngine. 10233bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org if (voice_channel_ != NULL && receive_streams_.empty() && 10243bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org !options_.conference_mode.GetWithDefaultIfUnset(false)) { 10253bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org config.audio_channel_id = 10263bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org static_cast<WebRtcVoiceMediaChannel*>(voice_channel_)->voe_channel(); 10273bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org } 10283bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 1029776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org receive_streams_[ssrc] = new WebRtcVideoReceiveStream( 1030776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org call_.get(), external_decoder_factory_, config, recv_codecs_); 1031d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1032d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1033d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1034d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1035d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 1036d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 1037d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const StreamParams& sp) const { 1038d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 1039d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1040d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remote_ssrc = ssrc; 1041d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 1042b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1043d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 1044257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 1045b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 1046b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 1047b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 1048b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 1049d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 1050d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 1051d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 1052b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1053d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 1054b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1055b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1056b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1057d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 1058d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (recv_codecs_[i].codec.id == kDefaultVideoCodecPref.payload_type) { 1059d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.fec = recv_codecs_[i].fec; 1060d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 rtx_ssrc; 1061d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 1062d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 1063d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].ssrc = rtx_ssrc; 1064d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].payload_type = 1065d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org recv_codecs_[i].rtx_payload_type; 1066b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1067d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org break; 1068b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1069b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1070b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1071b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1072b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1073b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { 1074b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 1075b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1076afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 1077afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return false; 1078b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1079b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1080575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1081d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator stream = 1082b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 1083b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 1084b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 1085b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1086b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1087d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org delete stream->second; 1088b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 1089b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1090b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1091b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1092b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1093b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 1094b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 1095b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 1096b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1097afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_unsignalled_ssrc_handler_.SetDefaultRenderer(this, renderer); 1098d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1099b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1100b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1101575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1102d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1103d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1104d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1105d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return false; 1106b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1108b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1109b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1111b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { 1113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1114afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org *renderer = default_unsignalled_ssrc_handler_.GetDefaultRenderer(); 1115afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return *renderer != NULL; 1116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1118575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1119d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1120d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1121d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(const StatsOptions& options, 1129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoMediaInfo* info) { 1130e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info->Clear(); 1131e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillSenderStats(info); 1132e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillReceiverStats(info); 1133e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillBandwidthEstimationStats(info); 1134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1136b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1137e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 1138575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1139e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1140e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org send_streams_.begin(); 1141e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != send_streams_.end(); 1142e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1143e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 1144e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1145e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1146e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1147e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 1148575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1149e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1150e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org receive_streams_.begin(); 1151e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != receive_streams_.end(); 1152e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1153e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 1154e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1155e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1156e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1157e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 1158e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoMediaInfo* video_media_info) { 1159e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Implement. 1160e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1161e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1162b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 1163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 1165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1166575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1167b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1168b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1169b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1170b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1171b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetCapturer(capturer); 1172b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1173b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1174b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1175b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1176b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1177b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1178b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1180b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1182b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1183b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1184b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1187d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1188d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11894e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 11904e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org call_->Receiver()->DeliverPacket( 11914e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()); 11924e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 11934e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 11944e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11954e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 11964e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11974e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 11984e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1199b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1200b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1201b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = 0; 1202b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!GetRtpSsrc(packet->data(), packet->length(), &ssrc)) { 1203b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1204b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1205b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1206afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org // TODO(pbos): Make sure that the unsignalled SSRC uses the video payload. 1207afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org // Also figure out whether RTX needs to be handled. 1208afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 1209afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDropPacket: 1210afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return; 1211afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDeliverPacket: 1212afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org break; 1213afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 1214b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 12151e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 12161e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 12171e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1218afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; 1219b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1220b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1221b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1222b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1223b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1224d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1225d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 12261e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 12271e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 12281e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1229b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTCP packet."; 1230b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1231b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1232b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1233b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 123426c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); 123526c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org call_->SignalNetworkState(ready ? webrtc::Call::kNetworkUp 123626c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org : webrtc::Call::kNetworkDown); 1237b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1238b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1239b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { 1240b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1241b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 1242b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1243575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1244b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1245b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1246b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1247b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1248ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org 1249ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org send_streams_[ssrc]->MuteStream(mute); 1250ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org return true; 1251b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1253b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1254b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1255587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " 1256587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 12573c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 12583c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1259d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 12603c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org recv_rtp_extensions_ = FilterRtpExtensions(extensions); 1261575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1262d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1263d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 1264d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 1265d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1266d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 1267d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1268b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1269b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1270b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1271b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1272b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1273587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " 1274587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 12753c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 12763c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 12773c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 12783c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org send_rtp_extensions_ = FilterRtpExtensions(extensions); 1279575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1280d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1281d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 1282d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 1283d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1284d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 1285d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1286b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1287b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1288b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1289b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int bps) { 1290b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1291b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetMaxSendBandwidth: " << bps; 1292b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1293b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1294b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1295b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 1296b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); 1297b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 1298575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 12995301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 13005301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_streams_.begin(); 13015301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it != send_streams_.end(); 13025301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ++it) { 13035301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it->second->SetOptions(options_); 13045301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1307b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1308b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1309b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1311b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1312d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Socket::OPT_RCVBUF, 1313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1315ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // Speculative change to increase the outbound socket buffer size. 1316ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // In b/15152257, we are seeing a significant number of packets discarded 1317ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // due to lack of socket buffer space, although it's not yet clear what the 1318ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // ideal value should be. 1319ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1320ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org rtc::Socket::OPT_SNDBUF, 1321ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org kVideoRtpBufferSize); 1322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1328d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(rtc::Message* msg) { 1329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 133242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoChannel2::OnLoadUpdate(Load load) { 1333575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 133442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 133542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org send_streams_.begin(); 133642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org it != send_streams_.end(); 133742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org ++it) { 133842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org it->second->OnCpuResolutionRequest(load == kOveruse 133942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org ? CoordinatedVideoAdapter::DOWNGRADE 134042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org : CoordinatedVideoAdapter::UPGRADE); 134142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org } 134242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 134342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 1344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { 1345d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendPacket(&packet); 1347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1350d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendRtcp(&packet); 1352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1355575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1365575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 13746ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 13756ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 13766ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 13776ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 13785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings) 13795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org : config(config), options(options), codec_settings(codec_settings) { 13806ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org} 13816ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 1382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 13847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 13855301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory, 13866ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 13875301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings, 13885301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const StreamParams& sp, 13895301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) 1390b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : call_(call), 13917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 1392b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org encoder_factory_(encoder_factory), 1393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 1394b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org parameters_(webrtc::VideoSendStream::Config(), options, codec_settings), 13957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_(NULL, webrtc::kVideoCodecUnknown, false), 1396b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org capturer_(NULL), 1397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 13985301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org muted_(false) { 13995301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 14005301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 14015301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 14025301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 14035301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 14045301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 14055301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 14065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 14075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings params; 14085301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (codec_settings.Get(¶ms)) { 14095301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodec(params); 14105301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 14155301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 14165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org call_->DestroyVideoSendStream(stream_); 14175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 14187fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 1419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void SetWebRtcFrameToBlack(webrtc::I420VideoFrame* video_frame) { 1422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(video_frame != NULL); 1423b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 1424b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 16, 1425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 1427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 1430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1431b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void CreateBlackFrame(webrtc::I420VideoFrame* video_frame, 1435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->CreateEmptyFrame( 1438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org width, height, width, (width + 1) / 2, (width + 1) / 2); 1439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetWebRtcFrameToBlack(video_frame); 1440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void ConvertToI420VideoFrame(const VideoFrame& frame, 1443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::I420VideoFrame* i420_frame) { 1444b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org i420_frame->CreateFrame( 1445b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch() * frame.GetHeight()), 1446b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetYPlane(), 1447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch() * ((frame.GetHeight() + 1) / 2)), 1448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetUPlane(), 1449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch() * ((frame.GetHeight() + 1) / 2)), 1450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetVPlane(), 1451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetWidth()), 1452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetHeight()), 1453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch()), 1454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch()), 1455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch())); 1456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1460b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 1461b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "InputFrame: " << frame->GetWidth() << "x" 1462b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << frame->GetHeight(); 1463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock before copying, can be called concurrently when swapping input source. 1464d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope frame_cs(&frame_lock_); 1465d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org ConvertToI420VideoFrame(*frame, &video_frame_); 1466d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org 1467d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 14685301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ == NULL) { 14695301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_WARNING) << "Capturer inputting frames before send codecs are " 14705301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org "configured, dropping."; 14715301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org return; 14725301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 1474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(format_.height == 0); 1475b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1476b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1477b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1478d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org if (muted_) { 1479d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org // Create a black frame to transmit instead. 1480d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org CreateBlackFrame(&video_frame_, 1481d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetWidth()), 1482d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetHeight())); 1483d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org } 1484b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1485c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions( 1486c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org video_frame_.width(), video_frame_.height(), capturer->IsScreencast()); 1487c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SwapFrame: " << video_frame_.width() << "x" 1489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << video_frame_.height() << " -> (codec) " 1490bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org << parameters_.encoder_config.streams.back().width << "x" 1491bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org << parameters_.encoder_config.streams.back().height; 1492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Input()->SwapFrame(&video_frame_); 1493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1496b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1502d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1503b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 15049359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (capturer == NULL) { 15059359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (stream_ != NULL) { 15069359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 15079359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org webrtc::I420VideoFrame black_frame; 15089359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org 15099359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int width = format_.width; 15109359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int height = format_.height; 15119359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int half_width = (width + 1) / 2; 15129359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org black_frame.CreateEmptyFrame( 15139359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org width, height, width, half_width, half_width); 15149359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org SetWebRtcFrameToBlack(&black_frame); 1515c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions(width, height, false); 15169359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org stream_->Input()->SwapFrame(&black_frame); 15179359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org } 1518b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1519b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1522b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1523b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1525b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1529b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1530b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1536b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1537b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1539b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1540d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1541b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1542b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1543b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 15446ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1545b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1546b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 1547bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.streams.back().max_framerate = 1548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1549c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions(format.width, format.height, false); 1550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1554b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1556ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1557d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1560b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1561b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1562963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org cricket::VideoCapturer* capturer; 1563963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org { 1564963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org rtc::CritScope cs(&lock_); 1565963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org if (capturer_ == NULL) { 1566963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org return false; 1567963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org } 1568963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer = capturer_; 1569963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer_ = NULL; 1570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1571963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer->SignalVideoFrame.disconnect(this); 1572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 15755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 15765301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1577d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 15785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings codec_settings; 15795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (parameters_.codec_settings.Get(&codec_settings)) { 15805301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, options); 15815301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } else { 15825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.options = options; 15835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15845301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 15857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 1586b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 15875301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings) { 1588d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 15895301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 15905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 15917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgwebrtc::VideoCodecType CodecTypeFromName(const std::string& name) { 15937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecNameMatches(name, kVp8CodecName)) { 15947fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecVP8; 15957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } else if (CodecNameMatches(name, kH264CodecName)) { 15967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecH264; 15977fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15987fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecUnknown; 15997fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 16007fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 16017fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder 16027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( 16037fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const VideoCodec& codec) { 16047fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 16057fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 16067fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Do not re-create encoders of the same type. 16077fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { 16087fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return allocated_encoder_; 16097fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 16107fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 16117fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ != NULL) { 16127fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder* encoder = 16137fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->CreateVideoEncoder(type); 16147fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder != NULL) { 16157fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(encoder, type, true); 16167fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 16177fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 16187fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 16197fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 16207fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder( 16217fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8), type, false); 16227fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 16237fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 16247fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 16257fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // support. 16267fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(false); 16277fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(NULL, webrtc::kVideoCodecUnknown, false); 16287fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 16297fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 16307fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( 16317fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder* encoder) { 16327fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder->external) { 16337fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->DestroyVideoEncoder(encoder->encoder); 16347fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } else { 16357fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org delete encoder->encoder; 16367fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 16377fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 16387fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 16395301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 16405301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings, 16415301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 16426ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org std::vector<webrtc::VideoStream> video_streams = 16436ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org encoder_factory_->CreateVideoStreams( 16445301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec, options, parameters_.config.rtp.ssrcs.size()); 16456ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (video_streams.empty()) { 1646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1648bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.streams = video_streams; 16495301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 16505301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec.height, 1651b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 1652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 16536ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 16547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); 16557fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org parameters_.config.encoder_settings.encoder = new_encoder.encoder; 16565301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 16575301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 16585301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 16595301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 16605301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org // Set RTX payload type if RTX is enabled. 16615301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 16625301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 1663543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1664543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org options.use_payload_padding.Get( 1665543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org ¶meters_.config.rtp.rtx.pad_with_redundant_payloads); 16665301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 16675301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 16685301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (IsNackEnabled(codec_settings.codec)) { 16695301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.nack.rtp_history_ms = kNackHistoryMs; 16705301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 16715301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 16725ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options.suspend_below_min_bitrate.Get( 16735ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org ¶meters_.config.suspend_below_min_bitrate); 16745ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org 16755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.codec_settings.Set(codec_settings); 16766ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 1677543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 16797fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (allocated_encoder_.encoder != new_encoder.encoder) { 16807fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 16817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_ = new_encoder; 16827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1684b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1685d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 1686d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 1687d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1688d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 1689d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1690d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1691d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1692c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( 1693c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int width, 1694c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int height, 1695efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org bool is_screencast) { 1696efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org if (last_dimensions_.width == width && last_dimensions_.height == height && 1697efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast == is_screencast) { 1698efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org // Configured using the same parameters, do not reconfigure. 1699efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org return; 1700efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org } 1701efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 1702efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.width = width; 1703efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.height = height; 1704efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast = is_screencast; 1705efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 1706bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org assert(!parameters_.encoder_config.streams.empty()); 1707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height; 1708c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1709c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org VideoCodecSettings codec_settings; 1710c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 1711c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org // Restrict dimensions according to codec max. 1712efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org if (!is_screencast) { 1713c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org if (codec_settings.codec.width < width) 1714c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org width = codec_settings.codec.width; 1715c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org if (codec_settings.codec.height < height) 1716c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org height = codec_settings.codec.height; 1717c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org } 1718c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1719bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config = parameters_.encoder_config; 1720bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = 1721bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_factory_->CreateVideoEncoderSettings(codec_settings.codec, 1722bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.options); 17236f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1724efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org if (is_screencast) { 1725efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org int screencast_min_bitrate_kbps; 1726efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org parameters_.options.screencast_min_bitrate.Get( 1727efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org &screencast_min_bitrate_kbps); 1728efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 1729efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org screencast_min_bitrate_kbps * 1000; 1730efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org encoder_config.content_type = webrtc::VideoEncoderConfig::kScreenshare; 1731efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org } else { 1732efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 0; 1733efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org encoder_config.content_type = webrtc::VideoEncoderConfig::kRealtimeVideo; 1734efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org } 1735efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 1736cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org VideoCodec codec = codec_settings.codec; 1737cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org codec.width = width; 1738cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org codec.height = height; 1739cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org 1740bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.streams = encoder_factory_->CreateVideoStreams( 1741bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org codec, parameters_.options, parameters_.config.rtp.ssrcs.size()); 17426f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1743bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); 1744bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 1745bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings( 1746bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org codec_settings.codec, 1747bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings); 1748bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 1749bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = NULL; 17506f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 17516f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (!stream_reconfigured) { 1752b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 1753b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 1754b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1755b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1756cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org 1757bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config = encoder_config; 1758b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1759b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1760b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 1761d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 17625301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org assert(stream_ != NULL); 1763b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1764b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 1765b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1766b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1767b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 1768d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 17695301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 17705301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org stream_->Stop(); 17715301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1772b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 1773b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1775e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoSenderInfo 1776e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 1777e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoSenderInfo info; 1778d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1779e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (size_t i = 0; i < parameters_.config.rtp.ssrcs.size(); ++i) { 1780e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(parameters_.config.rtp.ssrcs[i]); 1781e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1782e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1783c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org if (stream_ == NULL) { 1784c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org return info; 1785c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org } 1786c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org 1787e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 1788e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_input = stats.input_frame_rate; 1789e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 1790e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1791e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32_t, webrtc::StreamStats>::iterator it = 1792e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.substreams.begin(); 1793e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != stats.substreams.end(); 1794e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1795e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 1796e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::StreamStats stream_stats = it->second; 1797e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.bytes_sent += stream_stats.rtp_stats.bytes + 1798e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stream_stats.rtp_stats.header_bytes + 1799e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stream_stats.rtp_stats.padding_bytes; 1800e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_sent += stream_stats.rtp_stats.packets; 1801e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 1802e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1803e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1804e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (!stats.substreams.empty()) { 1805e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 1806e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::StreamStats first_stream_stats = stats.substreams.begin()->second; 1807e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.fraction_lost = 1808e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 1809e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org (1 << 8); 1810e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1811e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1812e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (capturer_ != NULL && !capturer_->IsMuted()) { 1813e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoFormat last_captured_frame_format; 1814e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, 1815e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &info.effects_frame_drops, 1816e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &info.capturer_frame_time, 1817e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &last_captured_frame_format); 1818e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 1819e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 1820e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.send_frame_width = 1821bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org static_cast<int>(parameters_.encoder_config.streams.front().width); 1822e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.send_frame_height = 1823bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org static_cast<int>(parameters_.encoder_config.streams.front().height); 1824e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1825e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1826e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Support or remove the following stats. 1827e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_cached = -1; 1828e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.rtt_ms = -1; 1829e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1830e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 1831e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1832e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 183342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::OnCpuResolutionRequest( 183442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org CoordinatedVideoAdapter::AdaptRequest adapt_request) { 183542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org rtc::CritScope cs(&lock_); 183642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org bool adapt_cpu; 183742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org parameters_.options.cpu_overuse_detection.Get(&adapt_cpu); 183842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org if (!adapt_cpu) { 183942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org return; 184042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org } 184142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org if (capturer_ == NULL || capturer_->video_adapter() == NULL) { 184242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org return; 184342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org } 184442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 184542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org capturer_->video_adapter()->OnCpuResolutionRequest(adapt_request); 184642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 184742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 1848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 1849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 1850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 1851b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 18526ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 18536f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 18546f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 1855bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = 1856bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_factory_->CreateVideoEncoderSettings(codec_settings.codec, 1857bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.options); 1858bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 1859bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org stream_ = call_->CreateVideoSendStream(parameters_.config, 1860bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config); 18616f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1862bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings( 1863bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org codec_settings.codec, 1864bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings); 18656f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1866bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = NULL; 18676f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1868b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 1869b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1871b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1873d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 1874d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::Call* call, 1875776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory, 1876d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::VideoReceiveStream::Config& config, 1877d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) 1878d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org : call_(call), 1879d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_(NULL), 1880b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org config_(config), 1881776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_(external_decoder_factory), 1882b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org renderer_(NULL), 1883d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_(-1), 1884b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org last_height_(-1) { 1885d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.renderer = this; 1886d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 1887d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRecvCodecs(recv_codecs); 1888d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1889d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1890d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 1891d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1892776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org ClearDecoders(); 1893d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1894d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1895d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 1896d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 1897d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 1898d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Base receive codecs off recv_codecs_ and set up using a 1899d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // DecoderFactory similar to send side. Pending webrtc:2854. 1900d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // Also set up default codecs if there's nothing in recv_codecs_. 1901776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org ClearDecoders(); 1902776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 1903776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org AllocatedDecoder allocated_decoder( 1904776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp8), false); 1905776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org allocated_decoders_.push_back(allocated_decoder); 1906776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 1907776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org webrtc::VideoReceiveStream::Decoder decoder; 1908776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org decoder.decoder = allocated_decoder.decoder; 1909776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org decoder.payload_type = kDefaultVideoCodecPref.payload_type; 1910776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org decoder.payload_name = "VP8"; 1911776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 1912776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org config_.decoders.push_back(decoder); 1913d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1914d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 1915d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1916257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.nack.rtp_history_ms = 1917257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org IsNackEnabled(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 1918257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.remb = IsRembEnabled(recv_codecs.begin()->codec); 1919257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 1920d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1921d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1922d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1923d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 1924d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 1925d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.extensions = extensions; 1926d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1927d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1928d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1929d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 1930d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (stream_ != NULL) { 1931d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1932d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1933d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 1934d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_->Start(); 1935d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1936d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1937776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders() { 1938776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org for (size_t i = 0; i < allocated_decoders_.size(); ++i) { 1939776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org if (allocated_decoders_[i].external) { 1940776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_->DestroyVideoDecoder( 1941776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org allocated_decoders_[i].decoder); 1942776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } else { 1943776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org delete allocated_decoders_[i].decoder; 1944776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 1945776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 1946776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org allocated_decoders_.clear(); 1947776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org} 1948776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 1949d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 1950d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::I420VideoFrame& frame, 1951d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int time_to_render_ms) { 1952d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1953d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ == NULL) { 1954d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 1955d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return; 1956d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1957d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1958d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 1959d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(frame.width(), frame.height()); 1960d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1961d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1962d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_VERBOSE) << "RenderFrame: (" << frame.width() << "x" << frame.height() 1963d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org << ")"; 1964d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1965d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const WebRtcVideoRenderFrame render_frame(&frame); 1966d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_->RenderFrame(&render_frame); 1967d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1968d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1969d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 1970d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org cricket::VideoRenderer* renderer) { 1971d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1972d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_ = renderer; 1973d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 1974d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(last_width_, last_height_); 1975d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1976d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1977d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1978d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 1979d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 1980d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // design. 1981d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1982d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return renderer_; 1983d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1984d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1985d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 1986d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int height) { 1987d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1988d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 1989d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 1990d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1991d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_ = width; 1992d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_ = height; 1993d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1994d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1995e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoReceiverInfo 1996e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 1997e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoReceiverInfo info; 1998e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 1999e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 2000e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.bytes_rcvd = stats.rtp_stats.bytes + stats.rtp_stats.header_bytes + 2001e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.rtp_stats.padding_bytes; 2002e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_rcvd = stats.rtp_stats.packets; 2003e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2004e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 2005e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 2006e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_output = stats.render_frame_rate; 2007e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2008d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope frame_cs(&renderer_lock_); 2009e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.frame_width = last_width_; 2010e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.frame_height = last_height_; 2011e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2012e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Support or remove the following stats. 2013e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_concealed = -1; 2014e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2015e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 2016e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 2017e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2018b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 2019b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 2020b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2021b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 2022b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 2023b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!codecs.empty()); 2024b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2025b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 2026b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 2027e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 2028b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, int> rtx_mapping; // video payload type -> rtx payload type. 2029b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2030b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 2031b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2032b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 2033b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 2034b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 2035b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2036b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 2037b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 2038b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 2039b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2040b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2041b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 2042e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 2043b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2044b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 2045b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 2046b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 2047b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.red_payload_type == -1); 2048b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 2049b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2050b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2051b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2052b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 2053b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 2054b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.ulpfec_payload_type == -1); 2055b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 2056b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2057b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2058b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2059b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 2060b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 2061b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 2062b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org &associated_payload_type)) { 2063b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RTX codec without associated payload type: " 2064b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 2065b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2066b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2067b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 2068b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2069b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2070b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2071b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 2072b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 2073b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2074b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2075b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 2076b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 2077b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2078b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2079b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 2080b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 2081b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!video_codecs.empty()); 2082b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2083e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 2084e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org it != rtx_mapping.end(); 2085e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org ++it) { 2086e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!payload_used[it->first]) { 2087e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 2088e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2089e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2090e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO) { 2091e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX not mapped to regular video codec."; 2092e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2093e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2094e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2095e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 2096b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Write tests that figure out that I have not verified that RTX 2097b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // codecs aren't mapped to bogus payloads. 2098b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 2099b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 2100b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtx_mapping[video_codecs[i].codec.id] != 0) { 2101b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2102b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2103b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2105b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 2106b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2108b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 2109b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 2110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) { 2111b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 2112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 21137fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const VideoCodecSettings& codec = mapped_codecs[i]; 21147fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecIsInternallySupported(codec.codec.name)) { 21157fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org supported_codecs.push_back(codec); 21167fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 21177fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 21187fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ == NULL) { 21197fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org continue; 21207fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 21217fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec> external_codecs = 21227fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->codecs(); 21237fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t c = 0; c < external_codecs.size(); ++c) { 21247fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecNameMatches(codec.codec.name, external_codecs[c].name)) { 21257fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org supported_codecs.push_back(codec); 21267fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org break; 21277fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 2128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return supported_codecs; 2131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 2134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 2136