webrtcvideoengine2.cc revision d4362cd3368d5fe542911c375b3a5c9f24b2f29d
1b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org/* 2b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * libjingle 3b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Copyright 2014 Google Inc. 4b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 5b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Redistribution and use in source and binary forms, with or without 6b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * modification, are permitted provided that the following conditions are met: 7b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 8b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 9b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * this list of conditions and the following disclaimer. 10b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 11b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * this list of conditions and the following disclaimer in the documentation 12b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * and/or other materials provided with the distribution. 13b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 3. The name of the author may not be used to endorse or promote products 14b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * derived from this software without specific prior written permission. 15b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 16b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org */ 27b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 28b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#ifdef HAVE_WEBRTC_VIDEO 29b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoengine2.h" 30b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 31c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org#include <algorithm> 323c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org#include <set> 33b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include <string> 34b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 35b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "libyuv/convert_from.h" 36b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videocapturer.h" 37b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videorenderer.h" 38df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org#include "talk/media/webrtc/constants.h" 39a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org#include "talk/media/webrtc/simulcast.h" 40b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideocapturer.h" 4182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org#include "talk/media/webrtc/webrtcvideoengine.h" 42b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoframe.h" 43b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvoiceengine.h" 44a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/buffer.h" 45a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/logging.h" 46a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/stringutils.h" 47b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/call.h" 4850fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org#include "webrtc/system_wrappers/interface/trace_event.h" 49776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org#include "webrtc/video_decoder.h" 50ab990ae43a2b84b103cb3c50bc38502375c13e68pbos@webrtc.org#include "webrtc/video_encoder.h" 51b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 52b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#define UNIMPLEMENTED \ 53b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Call to unimplemented function " << __FUNCTION__; \ 54b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(false) 55b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 56b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace cricket { 577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgnamespace { 587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { 597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::stringstream out; 607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '{'; 617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << codecs[i].ToString(); 637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (i != codecs.size() - 1) { 647fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << ", "; 657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '}'; 687fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return out.str(); 697fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 717fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic bool ValidateCodecFormats(const std::vector<VideoCodec>& codecs) { 727fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org bool has_video = false; 737fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 747fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!codecs[i].ValidateCodecFormat()) { 757fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return false; 767fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 777fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (codecs[i].GetCodecType() == VideoCodec::CODEC_VIDEO) { 787fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org has_video = true; 797fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 807fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (!has_video) { 827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org LOG(LS_ERROR) << "Setting codecs without a video codec is invalid: " 837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org << CodecVectorToString(codecs); 847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return false; 857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return true; 877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 89d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boströmstatic bool ValidateStreamParams(const StreamParams& sp) { 90d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (sp.ssrcs.empty()) { 91d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); 92d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 93d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 94d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 95d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström std::vector<uint32> primary_ssrcs; 96d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström sp.GetPrimarySsrcs(&primary_ssrcs); 97d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström std::vector<uint32> rtx_ssrcs; 98d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström sp.GetFidSsrcs(primary_ssrcs, &rtx_ssrcs); 99d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström for (uint32_t rtx_ssrc : rtx_ssrcs) { 100d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström bool rtx_ssrc_present = false; 101d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström for (uint32_t sp_ssrc : sp.ssrcs) { 102d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (sp_ssrc == rtx_ssrc) { 103d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström rtx_ssrc_present = true; 104d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström break; 105d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 106d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 107d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!rtx_ssrc_present) { 108d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) << "RTX SSRC '" << rtx_ssrc 109d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << "' missing from StreamParams ssrcs: " << sp.ToString(); 110d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 111d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 112d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 113d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 114d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_ERROR) 115d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 116d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << sp.ToString(); 117d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 118d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström } 119d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 120d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return true; 121d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström} 122d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström 1237fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic std::string RtpExtensionsToString( 1247fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1257fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::stringstream out; 1267fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '{'; 1277fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1287fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; 1297fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (i != extensions.size() - 1) { 1307fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << ", "; 1317fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1327fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1337fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '}'; 1347fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return out.str(); 1357fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 1367fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 13782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org// Merges two fec configs and logs an error if a conflict arises 13882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org// such that merging in diferent order would trigger a diferent output. 13982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.orgstatic void MergeFecConfig(const webrtc::FecConfig& other, 14082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::FecConfig* output) { 14182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.ulpfec_payload_type != -1) { 14282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->ulpfec_payload_type != -1 && 14382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type != other.ulpfec_payload_type) { 14482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: " 14582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->ulpfec_payload_type << " and " 14682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.ulpfec_payload_type; 14782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 14882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type = other.ulpfec_payload_type; 14982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 15082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.red_payload_type != -1) { 15182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->red_payload_type != -1 && 15282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type != other.red_payload_type) { 15382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging red_payload_type configs: " 15482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->red_payload_type << " and " 15582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.red_payload_type; 15682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 15782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type = other.red_payload_type; 15882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 15982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org} 1607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} // namespace 161b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 162b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// duration hasn't been implemented. 164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 166933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.orgstatic const int kDefaultQpMax = 56; 167933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org 168b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 169b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgconst char kH264CodecName[] = "H264"; 1717fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 172b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 173b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& requested_codec, 174b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* matching_codec) { 175b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 176b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 177b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *matching_codec = codecs[i]; 178b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 180b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 182b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 183b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1843c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic bool ValidateRtpHeaderExtensionIds( 1853c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1863c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::set<int> extensions_used; 1873c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1883c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (extensions[i].id < 0 || extensions[i].id >= 15 || 1893c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org !extensions_used.insert(extensions[i].id).second) { 1903c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; 1913c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1923c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1933c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1943c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return true; 1953c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 1963c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 197c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.orgstatic bool CompareRtpHeaderExtensionIds( 198c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const webrtc::RtpExtension& extension1, 199c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const webrtc::RtpExtension& extension2) { 200c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // Sorting on ID is sufficient, more than one extension per ID is unsupported. 201c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return extension1.id > extension2.id; 202c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org} 203c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 2043c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic std::vector<webrtc::RtpExtension> FilterRtpExtensions( 2053c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 2063c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::vector<webrtc::RtpExtension> webrtc_extensions; 2073c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 2083c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org // Unsupported extensions will be ignored. 2093c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (webrtc::RtpExtension::IsSupported(extensions[i].uri)) { 2103c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org webrtc_extensions.push_back(webrtc::RtpExtension( 2113c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org extensions[i].uri, extensions[i].id)); 2123c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } else { 2133c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; 2143c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 2153c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 216c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 217c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // Sort filtered headers to make sure that they can later be compared 218c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // regardless of in which order they were entered. 219c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::sort(webrtc_extensions.begin(), webrtc_extensions.end(), 220c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org CompareRtpHeaderExtensionIds); 2213c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return webrtc_extensions; 2223c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 2233c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 224c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.orgstatic bool RtpExtensionsHaveChanged( 225c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const std::vector<webrtc::RtpExtension>& before, 226c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const std::vector<webrtc::RtpExtension>& after) { 227c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before.size() != after.size()) 228c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 229c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org for (size_t i = 0; i < before.size(); ++i) { 230c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before[i].id != after[i].id) 231c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 232c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before[i].name != after[i].name) 233c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 234c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org } 235c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return false; 236c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org} 237c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 238a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.orgstd::vector<webrtc::VideoStream> 239f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateSimulcastVideoStreams( 240d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 241d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 242d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 243a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org // Use default factory for non-simulcast. 244a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org int max_qp = kDefaultQpMax; 245a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 246a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 247a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org int min_bitrate_kbps; 248a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org if (!codec.GetParam(kCodecParamMinBitrate, &min_bitrate_kbps) || 249a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org min_bitrate_kbps < kMinVideoBitrate) { 250a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org min_bitrate_kbps = kMinVideoBitrate; 2516ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org } 252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 253a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org int max_bitrate_kbps; 254a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org if (!codec.GetParam(kCodecParamMaxBitrate, &max_bitrate_kbps)) { 255a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org max_bitrate_kbps = 0; 256a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org } 257a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 258a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org return GetSimulcastConfig( 259a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org num_streams, 260a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org GetSimulcastBitrateMode(options), 261a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.width, 262a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.height, 263a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org max_bitrate_kbps * 1000, 264a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org max_qp, 265a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate); 266a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org} 267a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 268f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgstd::vector<webrtc::VideoStream> 269f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoStreams( 270a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoCodec& codec, 271a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoOptions& options, 272a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org size_t num_streams) { 273a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org if (num_streams != 1) 274a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org return CreateSimulcastVideoStreams(codec, options, num_streams); 275a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 276d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 277d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 278d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 279d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 28082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate; 281d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 282008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org stream.min_bitrate_bps = kMinVideoBitrate * 1000; 283a5f6fb53ba802fcf44e3c187d798c5a53ad555dfpbos@webrtc.org int max_bitrate_kbps; 284a5f6fb53ba802fcf44e3c187d798c5a53ad555dfpbos@webrtc.org if (!codec.GetParam(kCodecParamMaxBitrate, &max_bitrate_kbps) || 285a5f6fb53ba802fcf44e3c187d798c5a53ad555dfpbos@webrtc.org max_bitrate_kbps < kMaxVideoBitrate) { 286a5f6fb53ba802fcf44e3c187d798c5a53ad555dfpbos@webrtc.org max_bitrate_kbps = kMaxVideoBitrate; 287a5f6fb53ba802fcf44e3c187d798c5a53ad555dfpbos@webrtc.org } 288a5f6fb53ba802fcf44e3c187d798c5a53ad555dfpbos@webrtc.org 289a5f6fb53ba802fcf44e3c187d798c5a53ad555dfpbos@webrtc.org stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate_kbps * 1000; 290d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 291933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org int max_qp = kDefaultQpMax; 292d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 293d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 294d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 295d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 296d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 297d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 298b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 299f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgvoid* WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( 3006f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 3016f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoOptions& options) { 3027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecNameMatches(codec.name, kVp8CodecName)) { 303f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp8 = webrtc::VideoEncoder::GetDefaultVp8Settings(); 304f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org options.video_noise_reduction.Get(&encoder_settings_.vp8.denoisingOn); 305f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp8; 3066f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 307188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org if (CodecNameMatches(codec.name, kVp9CodecName)) { 308f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp9 = webrtc::VideoEncoder::GetDefaultVp9Settings(); 309f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org options.video_noise_reduction.Get(&encoder_settings_.vp9.denoisingOn); 310f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp9; 311188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } 3126f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 3136f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 3146f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 315afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgDefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler() 316afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org : default_recv_ssrc_(0), default_renderer_(NULL) {} 317afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 318afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgUnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc( 319a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org WebRtcVideoChannel2* channel, 320afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org uint32_t ssrc) { 321afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 322afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 323afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDropPacket; 324afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 325afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 326afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org StreamParams sp; 327afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org sp.ssrcs.push_back(ssrc); 328afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 329a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org if (!channel->AddRecvStream(sp, true)) { 330afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Could not create default receive stream."; 331afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 332afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 333afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(ssrc, default_renderer_); 334afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_recv_ssrc_ = ssrc; 335afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDeliverPacket; 336afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 337afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 33842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgWebRtcCallFactory::~WebRtcCallFactory() { 33942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 34042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgwebrtc::Call* WebRtcCallFactory::CreateCall( 34142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org const webrtc::Call::Config& config) { 34242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org return webrtc::Call::Create(config); 34342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 34442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 345afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgVideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { 346afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return default_renderer_; 347afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 348afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 349afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgvoid DefaultUnsignalledSsrcHandler::SetDefaultRenderer( 350afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 351afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoRenderer* renderer) { 352afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_renderer_ = renderer; 353afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { 354afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(default_recv_ssrc_, default_renderer_); 355afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 356afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 357afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 358f1f0d9a4cd53f4eacbf791cb7317612fa7382a45pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2(WebRtcVoiceEngine* voice_engine) 359b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : worker_thread_(NULL), 360f1f0d9a4cd53f4eacbf791cb7317612fa7382a45pbos@webrtc.org voice_engine_(voice_engine), 36182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org default_codec_format_(kDefaultVideoMaxWidth, 36282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org kDefaultVideoMaxHeight, 36382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org FPS_TO_INTERVAL(kDefaultVideoMaxFramerate), 364992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org FOURCC_ANY), 365b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org initialized_(false), 36642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_factory_(&default_call_factory_), 3670a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_(NULL), 3680a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_(NULL) { 369b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; 3707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 371587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 372587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 373587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpTimestampOffsetHeaderExtensionDefaultId)); 374587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 375587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 376587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 379b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Terminate(); 384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 38742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoEngine2::SetCallFactory(WebRtcCallFactory* call_factory) { 3887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(!initialized_); 38942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_factory_ = call_factory; 39042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 39142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 392d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgbool WebRtcVideoEngine2::Init(rtc::Thread* worker_thread) { 393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org worker_thread_ = worker_thread; 395b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(worker_thread_ != NULL); 396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 398b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 399b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 400b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::Terminate() { 402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Terminate"; 403b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 404b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = false; 405b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 406b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgint WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } 408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 409b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoEncoderConfig& config) { 4118fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org const VideoCodec& codec = config.max_codec; 412957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org bool supports_codec = false; 413957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org for (size_t i = 0; i < video_codecs_.size(); ++i) { 414957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org if (CodecNameMatches(video_codecs_[i].name, codec.name)) { 4152a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].width = codec.width; 4162a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].height = codec.height; 4172a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].framerate = codec.framerate; 418957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org supports_codec = true; 419957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org break; 420957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org } 421957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org } 422957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org 423957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org if (!supports_codec) { 424957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported: " 4258fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org << codec.ToString(); 4268fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return false; 4278fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 4288fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 429992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org default_codec_format_ = 430992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org VideoFormat(codec.width, 431992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org codec.height, 432992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org VideoFormat::FpsToInterval(codec.framerate), 433992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org FOURCC_ANY); 434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 4381ecbe45c7e4c9142896cb2810d699558518f4f28buildbot@webrtc.org const VideoOptions& options, 439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel) { 4407fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(initialized_); 441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "CreateChannel: " 442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (voice_channel != NULL ? "With" : "Without") 443fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org << " voice channel. Options: " << options.ToString(); 4447fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoChannel2* channel = 4457fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org new WebRtcVideoChannel2(call_factory_, 4463bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org voice_engine_, 4477fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org voice_channel, 448fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options, 4497fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_, 450f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org external_decoder_factory_); 451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!channel->Init()) { 452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete channel; 453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 455e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org channel->SetRecvCodecs(video_codecs_); 456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return channel; 457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 460b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 461b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 462b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return rtp_header_extensions_; 466b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { 469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Set up logging. 470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; 471b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if min_sev == -1, we keep the current log level. 472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (min_sev < 0) { 473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(min_sev == -1); 474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 475b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 476b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 477b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 4780a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalDecoderFactory( 4790a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoDecoderFactory* decoder_factory) { 4807fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(!initialized_); 4810a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_ = decoder_factory; 4820a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 4830a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 4840a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalEncoderFactory( 4850a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoEncoderFactory* encoder_factory) { 4867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(!initialized_); 487f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (external_encoder_factory_ == encoder_factory) 488f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org return; 489f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 490f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // No matter what happens we shouldn't hold on to a stale 491f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // WebRtcSimulcastEncoderFactory. 492f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset(); 493f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 494f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (encoder_factory && 495f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory( 496f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory->codecs())) { 497f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset( 498f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org new WebRtcSimulcastEncoderFactory(encoder_factory)); 499f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory = simulcast_encoder_factory_.get(); 500f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org } 5010a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_ = encoder_factory; 5027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5037fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 5040a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 5050a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 506b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 507b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 508b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 509b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 510b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 513b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 514b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 515b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 5168fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 5178fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 5188fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (codec.Matches(in)) { 5198fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 522b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 523b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 525b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// dimensions will be used for aspect ratio matching. 529b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 530b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& current, 531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* out) { 532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(out != NULL); 533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width != requested.height && 535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 536b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // 0xn and nx0 are invalid resolutions. 537b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 539b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 540b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec matching_codec; 541b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 542b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Codec not supported. 543b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 544b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 545b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 546b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->id = requested.id; 547b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->name = requested.name; 548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->preference = requested.preference; 549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 550ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org out->framerate = std::min(requested.framerate, matching_codec.framerate); 551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->feedback_params = requested.feedback_params; 5538fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width = requested.width; 5548fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height = requested.height; 5558fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 5568fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 5578fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 5588fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 5598fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org while (out->width > matching_codec.width) { 5608fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width /= 2; 5618fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height /= 2; 5628fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 5638fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 5648fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return out->width > 0 && out->height > 0; 565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 566b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 5797fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstd::vector<VideoCodec> WebRtcVideoEngine2::GetSupportedCodecs() const { 58082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org std::vector<VideoCodec> supported_codecs = DefaultVideoCodecList(); 5817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ == NULL) { 5837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 5847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 5857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs = 5877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->codecs(); 5887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 5897fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Don't add internally-supported codecs twice. 5907fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecIsInternallySupported(codecs[i].name)) { 5917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org continue; 5927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 5937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 594d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // External video encoders are given payloads 120-127. This also means that 595d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // we only support up to 8 external payload types. 596d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org const int kExternalVideoPayloadTypeBase = 120; 597d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org size_t payload_type = kExternalVideoPayloadTypeBase + i; 598d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org assert(payload_type < 128); 599d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org VideoCodec codec(static_cast<int>(payload_type), 6007fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].name, 6017fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_width, 6027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_height, 6037fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_fps, 6047fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 0); 6057fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 6067fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AddDefaultFeedbackParams(&codec); 6077fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org supported_codecs.push_back(codec); 6087fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 6097fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 6107fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 6117fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 61342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org WebRtcCallFactory* call_factory, 6143bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org WebRtcVoiceEngine* voice_engine, 615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel, 616fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org const VideoOptions& options, 6177fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 618f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory) 619b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 6208296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org voice_channel_id_(voice_channel != nullptr 6218296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org ? static_cast<WebRtcVoiceMediaChannel*>( 6228296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org voice_channel)->voe_channel() 6238296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org : -1), 6247fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 625f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org external_decoder_factory_(external_decoder_factory) { 626fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org SetDefaultOptions(); 627fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options_.SetAll(options); 628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call::Config config(this); 62942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org config.overuse_callback = this; 6303bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org if (voice_engine != NULL) { 6313bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org config.voice_engine = voice_engine->voe()->engine(); 6323bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org } 633fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org 63442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_.reset(call_factory->CreateCall(config)); 635b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 636b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 637b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 638b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 6396f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 6406f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 6416f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 64242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org options_.cpu_overuse_detection.Set(false); 643d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org options_.dscp.Set(false); 6445ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options_.suspend_below_min_bitrate.Set(false); 64542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org options_.video_noise_reduction.Set(true); 646efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org options_.screencast_min_bitrate.Set(0); 647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 650b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 651b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 653b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 654b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 655b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 656b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 657d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.begin(); 659b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != receive_streams_.end(); 660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::Init() { return true; } 666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 66796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgbool WebRtcVideoChannel2::CodecIsExternallySupported( 66896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::string& name) const { 66996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_encoder_factory_ == NULL) { 67096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 67196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 67296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 67396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec> external_codecs = 67496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_encoder_factory_->codecs(); 67596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t c = 0; c < external_codecs.size(); ++c) { 67696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (CodecNameMatches(name, external_codecs[c].name)) { 67796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return true; 67896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 67996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 68096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 68196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 68296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 68396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 68496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 68596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) 68696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const { 68796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 68896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 68996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodecSettings& codec = mapped_codecs[i]; 69096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (CodecIsInternallySupported(codec.codec.name) || 69196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CodecIsExternallySupported(codec.codec.name)) { 69296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org supported_codecs.push_back(codec); 69396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 69496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 69596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return supported_codecs; 69696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 69796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 69950fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvCodecs"); 700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 704b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 706b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 70796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without any video codecs."; 708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 709b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 71196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 71296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org FilterSupportedCodecs(mapped_codecs); 71396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 71496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (mapped_codecs.size() != supported_codecs.size()) { 71596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported video codecs."; 71696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 717b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 718b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 71996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org recv_codecs_ = supported_codecs; 720d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 721575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 722d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 723d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 724d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 725d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 726d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 727d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 728d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 729b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 730b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 731b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 732b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 73350fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendCodecs"); 734b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 735b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 736b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 737b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 738b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 739b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 740b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 741b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 742b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 743b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No video codecs supported by encoder factory."; 744b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 745b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 746b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 747b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 748b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 749a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoCodecSettings old_codec; 750a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (send_codec_.Get(&old_codec) && supported_codecs.front() == old_codec) { 751a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Using same codec, avoid reconfiguring. 752a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 753a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 754a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 755a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org send_codec_.Set(supported_codecs.front()); 756a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 757575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 758d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 759d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 760d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 761d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 762d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org assert(it->second != NULL); 763d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetCodec(supported_codecs.front()); 764d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 765b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 766008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org VideoCodec codec = supported_codecs.front().codec; 767008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org int bitrate_kbps; 768008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) && 769008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 770008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = bitrate_kbps * 1000; 771008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 772008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = 0; 773008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 774008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) && 775008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 776008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = bitrate_kbps * 1000; 777008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 778008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Do not reconfigure start bitrate unless it's specified and positive. 779008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 780008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 781008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) && 782008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 783008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = bitrate_kbps * 1000; 784008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 785008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = -1; 786008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 787008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 788008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org 789b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 790b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 791b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 792b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 793b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodecSettings codec_settings; 794b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 795b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 796b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 797b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 798b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *codec = codec_settings.codec; 799b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 800b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 801b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 802b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, 803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 805b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 806575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 811b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 812b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 813b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRender(bool render) { 814b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. 815b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); 816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send && !send_codec_.IsSet()) { 822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 823b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 827b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 829b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 830b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 831b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 832b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 833b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 834b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 835b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 836d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!ValidateStreamParams(sp)) 837b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 838b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 839b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 840b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 841b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Make sure none of sp.ssrcs are used, not just the identifying 842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ssrc. 843575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) != send_streams_.end()) { 845a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org LOG(LS_ERROR) << "Send stream with SSRC '" << ssrc << "' already exists."; 846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoSendStream* stream = 8506ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org new WebRtcVideoSendStream(call_.get(), 8517fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_, 8526ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options_, 8535301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_codec_, 8545301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp, 8555301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_rtp_extensions_); 8565301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 857b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 858b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 859b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 860b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 861b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 862b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 863b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 864b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 866b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 867b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 868b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 869b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 871b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { 873b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 874b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 875b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 876b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 877b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 878b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 879b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 885575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org WebRtcVideoSendStream* removed_stream; 886575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org { 887575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 888575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org std::map<uint32, WebRtcVideoSendStream*>::iterator it = 889575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.find(ssrc); 890575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org if (it == send_streams_.end()) { 891575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org return false; 892575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org } 893575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org 894575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org removed_stream = it->second; 895575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.erase(it); 896b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 897b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 898575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org delete removed_stream; 899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 905b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 907b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 908a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return AddRecvStream(sp, false); 909a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 910a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 911a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp, 912a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream) { 913d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström LOG(LS_INFO) << "AddRecvStream" << (default_stream ? " (default stream)" : "") 914d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström << ": " << sp.ToString(); 915d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström if (!ValidateStreamParams(sp)) 916d4362cd3368d5fe542911c375b3a5c9f24b2f29dPeter Boström return false; 917b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 918b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 919b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); // TODO(pbos): Is this ever valid? 920b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 921b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Check if any of the SSRCs overlap. 922575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 923a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org { 924a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org auto it = receive_streams_.find(ssrc); 925a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org if (it != receive_streams_.end()) { 926a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org if (default_stream || !it->second->IsDefaultStream()) { 927a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org LOG(LS_ERROR) << "Receive stream for SSRC '" << ssrc 928a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org << "' already exists."; 929a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return false; 930a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org } 931a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org delete it->second; 932a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org receive_streams_.erase(it); 933a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org } 934b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 935b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 936bd249bc711b3c9efd142eb8de3df489282fe693epbos@webrtc.org webrtc::VideoReceiveStream::Config config; 937d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ConfigureReceiverRtp(&config, sp); 9383bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 9393bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // Set up A/V sync if there is a VoiceChannel. 9403bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // TODO(pbos): The A/V is synched by the receiving channel. So we need to know 9413bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // the SSRC of the remote audio channel in order to sync the correct webrtc 9423bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // VoiceEngine channel. For now sync the first channel in non-conference to 9433bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // match existing behavior in WebRtcVideoEngine. 9448296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org if (voice_channel_id_ != -1 && receive_streams_.empty() && 9453bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org !options_.conference_mode.GetWithDefaultIfUnset(false)) { 9468296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org config.audio_channel_id = voice_channel_id_; 9473bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org } 9483bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 949a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org receive_streams_[ssrc] = 950a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org new WebRtcVideoReceiveStream(call_.get(), external_decoder_factory_, 951a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org default_stream, config, recv_codecs_); 952d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 953d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 954d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 955d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 956d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 957d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 958d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const StreamParams& sp) const { 959d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 960d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 961d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remote_ssrc = ssrc; 962d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 963b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 964d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 965257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 966b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 967b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 968b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 969b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 970d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 971d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 972d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 973b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 974d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 975b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 976b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 977b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 978d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 97982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec); 980b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 981b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 98282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 98382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org uint32 rtx_ssrc; 98482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 98582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 98682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = 98782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org config->rtp.rtx[recv_codecs_[i].codec.id]; 98882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.ssrc = rtx_ssrc; 98982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.payload_type = recv_codecs_[i].rtx_payload_type; 99082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 99182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 992b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 993b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 994b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { 995b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 996b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 997afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 998afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return false; 999b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1000b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1001575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1002d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator stream = 1003b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 1004b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 1005b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 1006b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1007b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1008d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org delete stream->second; 1009b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 1010b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1011b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1012b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1013b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1014b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 1015b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 1016b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 1017b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1018afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_unsignalled_ssrc_handler_.SetDefaultRenderer(this, renderer); 1019d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1020b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1021b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1022575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1023d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1024d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1025d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1026d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return false; 1027b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1028b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1029b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1030b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1031b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1032b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1033b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { 1034b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1035afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org *renderer = default_unsignalled_ssrc_handler_.GetDefaultRenderer(); 1036afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return *renderer != NULL; 1037b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1038b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1039575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1040d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1041d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1042d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1043b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1044b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1045b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1046b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1047b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1048b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1049058b1f17ac43b1fe69a8c18aaa7999ba88733dfdpbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(VideoMediaInfo* info) { 1050e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info->Clear(); 1051e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillSenderStats(info); 1052e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillReceiverStats(info); 10532b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org webrtc::Call::Stats stats = call_->GetStats(); 10542b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org FillBandwidthEstimationStats(stats, info); 10552b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org if (stats.rtt_ms != -1) { 10562b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org for (size_t i = 0; i < info->senders.size(); ++i) { 10572b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org info->senders[i].rtt_ms = stats.rtt_ms; 10582b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 10592b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 1060b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1061b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1062b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1063e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 1064575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1065e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1066e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org send_streams_.begin(); 1067e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != send_streams_.end(); 1068e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1069e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 1070e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1071e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1072e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1073e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 1074575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1075e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1076e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org receive_streams_.begin(); 1077e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != receive_streams_.end(); 1078e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1079e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 1080e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1081e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1082e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1083e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 10842b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org const webrtc::Call::Stats& stats, 1085e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoMediaInfo* video_media_info) { 10860bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo bwe_info; 10870bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_send_bandwidth = stats.send_bandwidth_bps; 10880bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_recv_bandwidth = stats.recv_bandwidth_bps; 10890bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.bucket_delay = stats.pacer_delay_ms; 10900bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 10910bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org // Get send stream bitrate stats. 10920bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 10930bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator stream = 10940bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org send_streams_.begin(); 10950bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stream != send_streams_.end(); 10960bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org ++stream) { 10970bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stream->second->FillBandwidthEstimationInfo(&bwe_info); 10980bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 10990bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org video_media_info->bw_estimations.push_back(bwe_info); 1100e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1101e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1102b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 1103b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 1105b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1106575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1108b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1109b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1111b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetCapturer(capturer); 1112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1127d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1128d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11294e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 11304e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org call_->Receiver()->DeliverPacket( 1131eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->size()); 11324e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 11334e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 11344e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11354e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 11364e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11374e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 11384e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1139b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1140b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1141b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = 0; 1142eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc)) { 1143b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1144b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1145b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1146a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org // TODO(pbos): Ignore unsignalled packets that don't use the video payload 1147a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org // (prevent creating default receivers for RTX configured as if it would 1148a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org // receive media payloads on those SSRCs). 1149afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 1150afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDropPacket: 1151afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return; 1152afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDeliverPacket: 1153afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org break; 1154afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 1155b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 11561e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 1157eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->size()) != 11581e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1159afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; 1160b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1161b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1162b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1165d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1166d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11671e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 1168eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->size()) != 11691e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1170b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTCP packet."; 1171b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1172b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1173b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1174b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 117526c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); 117626c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org call_->SignalNetworkState(ready ? webrtc::Call::kNetworkUp 117726c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org : webrtc::Call::kNetworkDown); 1178b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1180b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { 1181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1182b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 1183b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1184575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1188b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1189ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org 1190ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org send_streams_[ssrc]->MuteStream(mute); 1191ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org return true; 1192b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1193b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1194b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1195b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 119650fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvRtpHeaderExtensions"); 1197587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " 1198587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 11993c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 12003c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1201d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1202c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::vector<webrtc::RtpExtension> filtered_extensions = 1203c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org FilterRtpExtensions(extensions); 1204c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (!RtpExtensionsHaveChanged(recv_rtp_extensions_, filtered_extensions)) 1205c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1206c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1207c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org recv_rtp_extensions_ = filtered_extensions; 1208c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1209575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1210d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1211d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 1212d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 1213d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1214d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 1215d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1216b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1217b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1218b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1219b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1220b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 122150fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendRtpHeaderExtensions"); 1222587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " 1223587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 12243c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 12253c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 12263c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1227c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::vector<webrtc::RtpExtension> filtered_extensions = 1228c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org FilterRtpExtensions(extensions); 1229c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (!RtpExtensionsHaveChanged(send_rtp_extensions_, filtered_extensions)) 1230c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1231c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1232c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org send_rtp_extensions_ = filtered_extensions; 1233a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1234575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1235d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1236d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 1237d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 1238d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1239d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 1240d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1241b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1242b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1243b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1244008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int max_bitrate_bps) { 1245008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org LOG(LS_INFO) << "SetMaxSendBandwidth: " << max_bitrate_bps << "bps."; 1246008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (max_bitrate_bps <= 0) { 1247008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Unsetting max bitrate. 1248008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org max_bitrate_bps = -1; 1249008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1250008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 1251008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = max_bitrate_bps; 1252008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (max_bitrate_bps > 0 && 1253008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps > max_bitrate_bps) { 1254008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = max_bitrate_bps; 1255008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1256008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 1257b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1258b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1259b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1260b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 126150fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetOptions"); 1262a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetOptions: " << options.ToString(); 1263a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoOptions old_options = options_; 1264b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 1265a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (options_ == old_options) { 1266a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // No new options to set. 1267a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 1268a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1269d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org rtc::DiffServCodePoint dscp = options_.dscp.GetWithDefaultIfUnset(false) 1270d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org ? rtc::DSCP_AF41 1271d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org : rtc::DSCP_DEFAULT; 1272d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org MediaChannel::SetDscp(dscp); 1273575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 12745301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 12755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_streams_.begin(); 12765301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it != send_streams_.end(); 12775301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ++it) { 12785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it->second->SetOptions(options_); 12795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1280b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1281b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1282b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1283b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1284b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1285b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1286b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1287d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Socket::OPT_RCVBUF, 1288b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1289b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1290ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // Speculative change to increase the outbound socket buffer size. 1291ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // In b/15152257, we are seeing a significant number of packets discarded 1292ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // due to lack of socket buffer space, although it's not yet clear what the 1293ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // ideal value should be. 1294ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1295ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org rtc::Socket::OPT_SNDBUF, 1296ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org kVideoRtpBufferSize); 1297b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1298b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1299b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1300b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1301b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1302b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1303d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(rtc::Message* msg) { 1304b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 130742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoChannel2::OnLoadUpdate(Load load) { 1308575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 130942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 131042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org send_streams_.begin(); 131142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org it != send_streams_.end(); 131242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org ++it) { 131342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org it->second->OnCpuResolutionRequest(load == kOveruse 131442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org ? CoordinatedVideoAdapter::DOWNGRADE 131542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org : CoordinatedVideoAdapter::UPGRADE); 131642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org } 131742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 131842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 1319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { 1320d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendPacket(&packet); 1322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1325d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendRtcp(&packet); 1327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1328b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1330575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1332b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1333b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1334b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1335b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1336b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1340575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1342b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1343b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1345b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 13496ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 13506ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 13516ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 13526ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 13535301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings) 13545301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org : config(config), options(options), codec_settings(codec_settings) { 13556ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org} 13566ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 1357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 13597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 13606ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 13615301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings, 13625301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const StreamParams& sp, 13635301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) 1364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : call_(call), 13657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 1366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 1367b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org parameters_(webrtc::VideoSendStream::Config(), options, codec_settings), 13687fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_(NULL, webrtc::kVideoCodecUnknown, false), 1369b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org capturer_(NULL), 1370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 13719a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org muted_(false), 13729a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org old_adapt_changes_(0) { 13735301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 13745301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 13765301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 13775301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 13785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 13795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 13805301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13815301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings params; 13825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (codec_settings.Get(¶ms)) { 13835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodec(params); 13845301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1387b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1388b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 13895301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 13905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org call_->DestroyVideoSendStream(stream_); 13915301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 13927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 1393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1395b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void CreateBlackFrame(webrtc::I420VideoFrame* video_frame, 1396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1398b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->CreateEmptyFrame(width, height, width, (width + 1) / 2, 1399b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org (width + 1) / 2); 1400b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 16, 1401b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1402b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 128, 1403b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1404b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 128, 1405b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1406b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1409b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 141186196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::InputFrame"); 1412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "InputFrame: " << frame->GetWidth() << "x" 1413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << frame->GetHeight(); 1414afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org webrtc::I420VideoFrame video_frame(frame->GetVideoFrameBuffer(), 0, 0, 1415afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org frame->GetVideoRotation()); 1416d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 14175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ == NULL) { 14185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_WARNING) << "Capturer inputting frames before send codecs are " 14195301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org "configured, dropping."; 14205301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org return; 14215301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 142286196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 142386196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // Not sending, abort early to prevent expensive reconfigurations while 142486196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // setting up codecs etc. 142586196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (!sending_) 142686196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org return; 142786196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 1428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 1429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(format_.height == 0); 1430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1431b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1433d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org if (muted_) { 1434d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org // Create a black frame to transmit instead. 1435afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org CreateBlackFrame(&video_frame, 1436d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetWidth()), 1437d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetHeight())); 1438d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org } 1439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1440c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions( 1441afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org video_frame.width(), video_frame.height(), capturer->IsScreencast()); 1442c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1443af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org LOG(LS_VERBOSE) << "IncomingCapturedFrame: " << video_frame.width() << "x" 1444afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org << video_frame.height() << " -> (codec) " 1445bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org << parameters_.encoder_config.streams.back().width << "x" 1446bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org << parameters_.encoder_config.streams.back().height; 1447af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(video_frame); 1448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1452b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetCapturer"); 1453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1458d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14609359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (capturer == NULL) { 14619359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (stream_ != NULL) { 14629359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 14639359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org webrtc::I420VideoFrame black_frame; 14649359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org 1465b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org CreateBlackFrame(&black_frame, last_dimensions_.width, 1466b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org last_dimensions_.height); 1467af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(black_frame); 14689359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org } 1469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1471b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1475b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1476b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1477b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1478b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1479b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1480b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1481b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1483b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1484b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1485b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1486b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1490b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1491d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 14956ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1496b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 1498bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.streams.back().max_framerate = 1499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1500c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions(format.width, format.height, false); 1501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1503b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1504b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1505b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1506b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1507ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1508d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1509b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1510b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1513963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org cricket::VideoCapturer* capturer; 1514963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org { 1515963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org rtc::CritScope cs(&lock_); 15169a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ == NULL) 1517963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org return false; 15189a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 15199a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) 15209a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org old_adapt_changes_ += capturer_->video_adapter()->adaptation_changes(); 15219a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 1522963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer = capturer_; 1523963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer_ = NULL; 1524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1525963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer->SignalVideoFrame.disconnect(this); 1526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 15295301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 15305301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1531d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 15325301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings codec_settings; 15335301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (parameters_.codec_settings.Get(&codec_settings)) { 15345301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, options); 15355301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } else { 15365301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.options = options; 15375301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15385301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 15397fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 1540b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 15415301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings) { 1542d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 15435301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 15445301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 15457fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15467fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgwebrtc::VideoCodecType CodecTypeFromName(const std::string& name) { 15477fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecNameMatches(name, kVp8CodecName)) { 15487fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecVP8; 1549188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } else if (CodecNameMatches(name, kVp9CodecName)) { 1550188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return webrtc::kVideoCodecVP9; 15517fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } else if (CodecNameMatches(name, kH264CodecName)) { 15527fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecH264; 15537fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecUnknown; 15557fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 15567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder 15587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( 15597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const VideoCodec& codec) { 15607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 15617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Do not re-create encoders of the same type. 15637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { 15647fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return allocated_encoder_; 15657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ != NULL) { 15687fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder* encoder = 15697fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->CreateVideoEncoder(type); 15707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder != NULL) { 15717fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(encoder, type, true); 15727fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15737fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15747fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15757fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 15767fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder( 15777fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8), type, false); 1578188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } else if (type == webrtc::kVideoCodecVP9) { 1579188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return AllocatedEncoder( 1580188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp9), type, false); 15817fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 15847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // support. 15857fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(false); 15867fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(NULL, webrtc::kVideoCodecUnknown, false); 15877fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 15887fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15897fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( 15907fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder* encoder) { 15917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder->external) { 15927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->DestroyVideoEncoder(encoder->encoder); 15937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } else { 15947fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org delete encoder->encoder; 15957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 15977fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15985301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 15995301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings, 16005301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1601a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org parameters_.encoder_config = 1602a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 160386196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (parameters_.encoder_config.streams.empty()) 1604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1605a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 16065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 16075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec.height, 1608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 1609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 16106ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 16117fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); 16127fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org parameters_.config.encoder_settings.encoder = new_encoder.encoder; 16135301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 16145301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 16155301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 16165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 16175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org // Set RTX payload type if RTX is enabled. 16185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 1619b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (codec_settings.rtx_payload_type == -1) { 1620b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 1621b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type. Ignoring."; 1622b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.ssrcs.clear(); 1623b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } else { 1624b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 1625b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 16265301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 16275301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 16285301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (IsNackEnabled(codec_settings.codec)) { 16295301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.nack.rtp_history_ms = kNackHistoryMs; 16305301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 16315301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 16325ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options.suspend_below_min_bitrate.Get( 16335ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org ¶meters_.config.suspend_below_min_bitrate); 16345ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org 16355301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.codec_settings.Set(codec_settings); 16366ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 1637543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1638b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 16397fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (allocated_encoder_.encoder != new_encoder.encoder) { 16407fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 16417fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_ = new_encoder; 16427fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1643b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1645d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 1646d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 1647d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1648d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 1649d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1650d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1651d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1652a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgwebrtc::VideoEncoderConfig 1653a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( 1654a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const Dimensions& dimensions, 1655a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const VideoCodec& codec) const { 1656a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config; 1657a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (dimensions.is_screencast) { 1658a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int screencast_min_bitrate_kbps; 1659a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org parameters_.options.screencast_min_bitrate.Get( 1660a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org &screencast_min_bitrate_kbps); 1661a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 1662a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org screencast_min_bitrate_kbps * 1000; 1663a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.content_type = webrtc::VideoEncoderConfig::kScreenshare; 1664a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } else { 1665a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 0; 1666a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.content_type = webrtc::VideoEncoderConfig::kRealtimeVideo; 1667a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1668a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1669a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Restrict dimensions according to codec max. 1670a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int width = dimensions.width; 1671a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int height = dimensions.height; 1672a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (!dimensions.is_screencast) { 1673a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.width < width) 1674a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org width = codec.width; 1675a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.height < height) 1676a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org height = codec.height; 1677a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1678a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1679a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoCodec clamped_codec = codec; 1680a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.width = width; 1681a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.height = height; 1682a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1683f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_config.streams = CreateVideoStreams( 1684a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec, parameters_.options, parameters_.config.rtp.ssrcs.size()); 1685a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1686a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Conference mode screencast uses 2 temporal layers split at 100kbit. 1687a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (parameters_.options.conference_mode.GetWithDefaultIfUnset(false) && 1688a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org dimensions.is_screencast && encoder_config.streams.size() == 1) { 168946d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault(); 169046d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org 169146d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // For screenshare in conference mode, tl0 and tl1 bitrates are piggybacked 169246d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // on the VideoCodec struct as target and max bitrates, respectively. 169346d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // See eg. webrtc::VP8EncoderImpl::SetRates(). 169446d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].target_bitrate_bps = 169546d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000; 169646d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].max_bitrate_bps = config.tl1_bitrate_kbps * 1000; 1697a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.clear(); 1698a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.push_back( 169946d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000); 1700a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1701a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return encoder_config; 1702a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 1703a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1704c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( 1705c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int width, 1706c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int height, 1707efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org bool is_screencast) { 1708efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org if (last_dimensions_.width == width && last_dimensions_.height == height && 1709efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast == is_screencast) { 1710efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org // Configured using the same parameters, do not reconfigure. 1711efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org return; 1712efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org } 1713a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetDimensions: " << width << "x" << height 1714a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org << (is_screencast ? " (screencast)" : " (not screencast)"); 1715efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 1716efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.width = width; 1717efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.height = height; 1718efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast = is_screencast; 1719efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 1720bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org assert(!parameters_.encoder_config.streams.empty()); 1721c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1722c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org VideoCodecSettings codec_settings; 1723c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 1724c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1725a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config = 1726a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 1727a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1728bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = 1729f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org ConfigureVideoEncoderSettings(codec_settings.codec, parameters_.options); 17306f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1731bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); 1732bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 1733bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = NULL; 17346f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 17356f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (!stream_reconfigured) { 1736b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 1737b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 1738b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1739b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1740cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org 1741bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config = encoder_config; 1742b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1743b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1744b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 1745d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 17465301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org assert(stream_ != NULL); 1747b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1748b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 1749b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1750b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1751b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 1752d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 17535301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 17545301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org stream_->Stop(); 17555301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1756b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 1757b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1758b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1759e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoSenderInfo 1760e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 1761e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoSenderInfo info; 176277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org webrtc::VideoSendStream::Stats stats; 176377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org { 176477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org rtc::CritScope cs(&lock_); 176577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (uint32_t ssrc : parameters_.config.rtp.ssrcs) 176677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.add_ssrc(ssrc); 176777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 176877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (size_t i = 0; i < parameters_.encoder_config.streams.size(); ++i) { 176977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (i == parameters_.encoder_config.streams.size() - 1) { 177077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 177177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].max_bitrate_bps; 177277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } else { 177377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 177477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].target_bitrate_bps; 177577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 177677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 1777e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 177877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (stream_ == NULL) 177977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org return info; 1780c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org 178177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org stats = stream_->GetStats(); 178277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 17839a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes = old_adapt_changes_; 17849a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = CoordinatedVideoAdapter::ADAPTREASON_NONE; 17859a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 17869a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ != NULL) { 17879a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (!capturer_->IsMuted()) { 17889a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org VideoFormat last_captured_frame_format; 17899a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, &info.effects_frame_drops, 17909a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &info.capturer_frame_time, 17919a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &last_captured_frame_format); 17929a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 17939a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 17949a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 17959a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) { 17969a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes += capturer_->video_adapter()->adaptation_changes(); 17979a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = capturer_->video_adapter()->adapt_reason(); 17989a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 179977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 180077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 1801e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_input = stats.input_frame_rate; 1802e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 18033e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.avg_encode_ms = stats.avg_encode_time_ms; 18043e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.encode_usage_percent = stats.encode_usage_percent; 1805e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 180677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.nominal_bitrate = stats.media_bitrate_bps; 180777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 1808273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_width = 0; 1809273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_height = 0; 181009c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 1811e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.substreams.begin(); 181209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 1813e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 181409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats stream_stats = it->second; 1815cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_sent += stream_stats.rtp_stats.transmitted.payload_bytes + 1816cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.header_bytes + 1817cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.padding_bytes; 1818cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_sent += stream_stats.rtp_stats.transmitted.packets; 1819e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 182009c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.width > info.send_frame_width) 182109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_width = stream_stats.width; 182209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.height > info.send_frame_height) 182309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_height = stream_stats.height; 18241d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_rcvd += stream_stats.rtcp_packet_type_counts.fir_packets; 18251d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_rcvd += stream_stats.rtcp_packet_type_counts.nack_packets; 18261d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_rcvd += stream_stats.rtcp_packet_type_counts.pli_packets; 1827e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1828e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1829e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (!stats.substreams.empty()) { 1830e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 183109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats first_stream_stats = 183209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org stats.substreams.begin()->second; 1833e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.fraction_lost = 1834e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 1835e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org (1 << 8); 1836e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1837e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1838e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 1839e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1840e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 18410bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo( 18420bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo* bwe_info) { 18430bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope cs(&lock_); 18440bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org if (stream_ == NULL) { 18450bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org return; 18460bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 18470bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 184809c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 18490bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stats.substreams.begin(); 185009c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 18510bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->transmit_bitrate += it->second.total_bitrate_bps; 18520bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps; 18530bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 1854891d48393e5ccd2f5e03d509c544c00a3d88cbbcpbos@webrtc.org bwe_info->target_enc_bitrate += stats.target_media_bitrate_bps; 185577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org bwe_info->actual_enc_bitrate += stats.media_bitrate_bps; 18560bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org} 18570bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 185842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::OnCpuResolutionRequest( 185942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org CoordinatedVideoAdapter::AdaptRequest adapt_request) { 186042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org rtc::CritScope cs(&lock_); 186142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org bool adapt_cpu; 186242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org parameters_.options.cpu_overuse_detection.Get(&adapt_cpu); 18639a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (!adapt_cpu) 186442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org return; 18659a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ == NULL || capturer_->video_adapter() == NULL) 186642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org return; 186742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 186842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org capturer_->video_adapter()->OnCpuResolutionRequest(adapt_request); 186942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 187042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 1871b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 1872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 1873b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 1874b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 18756ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 18766f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 18776f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 1878bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = 1879f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org ConfigureVideoEncoderSettings(codec_settings.codec, parameters_.options); 1880bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 1881b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoSendStream::Config config = parameters_.config; 1882b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { 1883b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 1884b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type the set codec. Ignoring RTX."; 1885b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org config.rtp.rtx.ssrcs.clear(); 1886b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 1887b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org stream_ = call_->CreateVideoSendStream(config, parameters_.encoder_config); 18886f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1889bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = NULL; 18906f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 1892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1896d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 1897d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::Call* call, 1898776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory, 1899a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream, 1900d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::VideoReceiveStream::Config& config, 1901d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) 1902d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org : call_(call), 1903d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_(NULL), 1904a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org default_stream_(default_stream), 1905b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org config_(config), 1906776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_(external_decoder_factory), 1907b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org renderer_(NULL), 1908d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_(-1), 1909fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org last_height_(-1), 1910fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_(-1), 1911fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_(0) { 1912d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.renderer = this; 1913d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 1914d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRecvCodecs(recv_codecs); 1915d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1916d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1917d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 1918d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 191996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org ClearDecoders(&allocated_decoders_); 1920d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1921d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 192296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::AllocatedDecoder 192396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder( 192496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* old_decoders, 192596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodec& codec) { 192696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 1927776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 192896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < old_decoders->size(); ++i) { 192996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*old_decoders)[i].type == type) { 193096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder decoder = (*old_decoders)[i]; 193196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org (*old_decoders)[i] = old_decoders->back(); 193296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org old_decoders->pop_back(); 193396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return decoder; 193496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 193596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 1936776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 193796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_decoder_factory_ != NULL) { 193896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder* decoder = 193996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_decoder_factory_->CreateVideoDecoder(type); 194096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (decoder != NULL) { 194196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(decoder, type, true); 194296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 194396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 1944776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 194596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 194696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder( 194796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp8), type, false); 194896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 1949d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1950b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (type == webrtc::kVideoCodecVP9) { 1951b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org return AllocatedDecoder( 1952b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp9), type, false); 1953b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 1954b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org 195596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 195696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // support. 195796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org assert(false); 195896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(NULL, webrtc::kVideoCodecUnknown, false); 195996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 196096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 196196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 196296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 196396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder> old_decoders = allocated_decoders_; 196496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.clear(); 196596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.clear(); 196696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < recv_codecs.size(); ++i) { 196796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder allocated_decoder = 196896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CreateOrReuseVideoDecoder(&old_decoders, recv_codecs[i].codec); 196996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.push_back(allocated_decoder); 1970d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 197196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoReceiveStream::Decoder decoder; 197296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.decoder = allocated_decoder.decoder; 197396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_type = recv_codecs[i].codec.id; 197496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_name = recv_codecs[i].codec.name; 197596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.push_back(decoder); 197696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 197796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 197896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 197996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 1980257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.nack.rtp_history_ms = 1981257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org IsNackEnabled(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 1982257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.remb = IsRembEnabled(recv_codecs.begin()->codec); 1983257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 198496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org ClearDecoders(&old_decoders); 1985d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1986d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1987d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1988d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 1989d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 1990d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.extensions = extensions; 1991d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1992d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1993d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1994d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 1995d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (stream_ != NULL) { 1996d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1997d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1998d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 1999d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_->Start(); 2000d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2001d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 200296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( 200396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* allocated_decoders) { 200496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < allocated_decoders->size(); ++i) { 200596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*allocated_decoders)[i].external) { 2006776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_->DestroyVideoDecoder( 200796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org (*allocated_decoders)[i].decoder); 2008776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } else { 200996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org delete (*allocated_decoders)[i].decoder; 2010776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 2011776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 201296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders->clear(); 2013776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org} 2014776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 2015d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 2016d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::I420VideoFrame& frame, 2017d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int time_to_render_ms) { 2018d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2019fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 2020fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (first_frame_timestamp_ < 0) 2021fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_ = frame.timestamp(); 2022fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t rtp_time_elapsed_since_first_frame = 2023fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (timestamp_wraparound_handler_.Unwrap(frame.timestamp()) - 2024fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_); 2025fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t elapsed_time_ms = rtp_time_elapsed_since_first_frame / 2026fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (cricket::kVideoCodecClockrate / 1000); 2027fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (frame.ntp_time_ms() > 0) 2028fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_ = frame.ntp_time_ms() - elapsed_time_ms; 2029fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 2030d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ == NULL) { 2031d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 2032d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return; 2033d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2034d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2035d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 2036d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(frame.width(), frame.height()); 2037d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2038d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2039d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_VERBOSE) << "RenderFrame: (" << frame.width() << "x" << frame.height() 2040d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org << ")"; 2041d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 20422386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org const WebRtcVideoFrame render_frame( 20432386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org frame.video_frame_buffer(), 20442386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org elapsed_time_ms * rtc::kNumNanosecsPerMillisec, 20452386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org frame.render_time_ms() * rtc::kNumNanosecsPerMillisec); 2046d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_->RenderFrame(&render_frame); 2047d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2048d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 20490d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsTextureSupported() const { 20500d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org return true; 20510d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org} 20520d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org 2053a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsDefaultStream() const { 2054a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return default_stream_; 2055a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 2056a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 2057d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 2058d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org cricket::VideoRenderer* renderer) { 2059d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2060d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_ = renderer; 2061d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 2062d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(last_width_, last_height_); 2063d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2064d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2065d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2066d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 2067d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 2068d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // design. 2069d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2070d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return renderer_; 2071d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2072d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2073d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 2074d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int height) { 2075d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2076d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 2077d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 2078d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2079d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_ = width; 2080d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_ = height; 2081d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2082d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2083e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoReceiverInfo 2084e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 2085e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoReceiverInfo info; 2086e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 2087e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 2088cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_rcvd = stats.rtp_stats.transmitted.payload_bytes + 2089cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.header_bytes + 2090cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.padding_bytes; 2091cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_rcvd = stats.rtp_stats.transmitted.packets; 2092e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2093e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 2094e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 2095e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_output = stats.render_frame_rate; 2096e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 20971d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org { 20981d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org rtc::CritScope frame_cs(&renderer_lock_); 20991d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_width = last_width_; 21001d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_height = last_height_; 21011d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.capture_start_ntp_time_ms = estimated_remote_start_ntp_time_ms_; 21021d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org } 21031d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org 210409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.decode_ms = stats.decode_ms; 210509c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.max_decode_ms = stats.max_decode_ms; 210609c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.current_delay_ms = stats.current_delay_ms; 210709c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.target_delay_ms = stats.target_delay_ms; 210809c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.jitter_buffer_ms = stats.jitter_buffer_ms; 210909c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.min_playout_delay_ms = stats.min_playout_delay_ms; 211009c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.render_delay_ms = stats.render_delay_ms; 211109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org 21121d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_sent = stats.rtcp_packet_type_counts.fir_packets; 21131d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_sent = stats.rtcp_packet_type_counts.pli_packets; 21141d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets; 2115e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2116e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 2117e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 2118e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 2120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 2121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2122a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgbool WebRtcVideoChannel2::VideoCodecSettings::operator==( 2123a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2124a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return codec == other.codec && 2125a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && 2126a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.red_payload_type == other.fec.red_payload_type && 2127a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org rtx_payload_type == other.rtx_payload_type; 2128a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 2129a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 2131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 2132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!codecs.empty()); 2133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 2135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 2136e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 2137d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // |rtx_mapping| maps video payload type to rtx payload type. 2138d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org std::map<int, int> rtx_mapping; 2139b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2140b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 2141b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2142b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 2143b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 2144b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 2145b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2146b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 2147b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 2148b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 2149b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2150b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2151b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 2152e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 2153b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2154b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 2155b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 2156b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 2157b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.red_payload_type == -1); 2158b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 2159b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2160b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2161b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2162b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 2163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 2164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.ulpfec_payload_type == -1); 2165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 2166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2167b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2168b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2169b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 2170b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 2171b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 2172e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org &associated_payload_type) || 2173e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org !IsValidRtpPayloadType(associated_payload_type)) { 2174e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org LOG(LS_ERROR) 2175e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << "RTX codec with invalid or no associated payload type: " 2176e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << in_codec.ToString(); 2177b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2178b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 2180b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2182b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2183b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 2184b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 2185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 2188b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 2189b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2190b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2191b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 2192b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 2193b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!video_codecs.empty()); 2194b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2195e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 2196e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org it != rtx_mapping.end(); 2197e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org ++it) { 2198e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!payload_used[it->first]) { 2199e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 2200e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2201e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 22028f27fcce79584378da97f0d84574564799e138d6andrew@webrtc.org if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO) { 22038f27fcce79584378da97f0d84574564799e138d6andrew@webrtc.org LOG(LS_ERROR) << "RTX not mapped to regular video codec."; 2204e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2205e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2206e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2207e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 2208b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Write tests that figure out that I have not verified that RTX 2209b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // codecs aren't mapped to bogus payloads. 2210b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 2211b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 22128f27fcce79584378da97f0d84574564799e138d6andrew@webrtc.org if (rtx_mapping[video_codecs[i].codec.id] != 0) { 2213b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2214b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2215b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2216b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2217b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 2218b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2219b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2220b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 2221b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2222b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 2223