webrtcvideoengine2.cc revision b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3
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 897fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstatic std::string RtpExtensionsToString( 907fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 917fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org std::stringstream out; 927fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '{'; 937fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 947fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; 957fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (i != extensions.size() - 1) { 967fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << ", "; 977fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 987fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 997fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org out << '}'; 1007fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return out.str(); 1017fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 1027fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 10382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org// Merges two fec configs and logs an error if a conflict arises 10482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org// such that merging in diferent order would trigger a diferent output. 10582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.orgstatic void MergeFecConfig(const webrtc::FecConfig& other, 10682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::FecConfig* output) { 10782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.ulpfec_payload_type != -1) { 10882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->ulpfec_payload_type != -1 && 10982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type != other.ulpfec_payload_type) { 11082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: " 11182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->ulpfec_payload_type << " and " 11282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.ulpfec_payload_type; 11382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 11482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->ulpfec_payload_type = other.ulpfec_payload_type; 11582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 11682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (other.red_payload_type != -1) { 11782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (output->red_payload_type != -1 && 11882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type != other.red_payload_type) { 11982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org LOG(LS_WARNING) << "Conflict merging red_payload_type configs: " 12082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << output->red_payload_type << " and " 12182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org << other.red_payload_type; 12282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 12382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org output->red_payload_type = other.red_payload_type; 12482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 12582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org} 1267fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} // namespace 127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// duration hasn't been implemented. 130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 132933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.orgstatic const int kDefaultQpMax = 56; 133933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org 134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1367fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgconst char kH264CodecName[] = "H264"; 1377fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 138b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 139b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& requested_codec, 140b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* matching_codec) { 141b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 142b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 143b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *matching_codec = codecs[i]; 144b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 145b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 146b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 147b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 148b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 149b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1503c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic bool ValidateRtpHeaderExtensionIds( 1513c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1523c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::set<int> extensions_used; 1533c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1543c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (extensions[i].id < 0 || extensions[i].id >= 15 || 1553c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org !extensions_used.insert(extensions[i].id).second) { 1563c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; 1573c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1583c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1593c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1603c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return true; 1613c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 1623c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 163c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.orgstatic bool CompareRtpHeaderExtensionIds( 164c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const webrtc::RtpExtension& extension1, 165c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const webrtc::RtpExtension& extension2) { 166c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // Sorting on ID is sufficient, more than one extension per ID is unsupported. 167c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return extension1.id > extension2.id; 168c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org} 169c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1703c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic std::vector<webrtc::RtpExtension> FilterRtpExtensions( 1713c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1723c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::vector<webrtc::RtpExtension> webrtc_extensions; 1733c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1743c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org // Unsupported extensions will be ignored. 1753c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (webrtc::RtpExtension::IsSupported(extensions[i].uri)) { 1763c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org webrtc_extensions.push_back(webrtc::RtpExtension( 1773c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org extensions[i].uri, extensions[i].id)); 1783c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } else { 1793c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; 1803c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1813c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 182c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 183c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // Sort filtered headers to make sure that they can later be compared 184c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org // regardless of in which order they were entered. 185c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::sort(webrtc_extensions.begin(), webrtc_extensions.end(), 186c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org CompareRtpHeaderExtensionIds); 1873c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return webrtc_extensions; 1883c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 1893c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 190c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.orgstatic bool RtpExtensionsHaveChanged( 191c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const std::vector<webrtc::RtpExtension>& before, 192c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org const std::vector<webrtc::RtpExtension>& after) { 193c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before.size() != after.size()) 194c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 195c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org for (size_t i = 0; i < before.size(); ++i) { 196c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before[i].id != after[i].id) 197c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 198c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (before[i].name != after[i].name) 199c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 200c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org } 201c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return false; 202c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org} 203c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 204a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.orgstd::vector<webrtc::VideoStream> 205f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateSimulcastVideoStreams( 206d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 207d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 208d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 209a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org // Use default factory for non-simulcast. 210a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org int max_qp = kDefaultQpMax; 211a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 212a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 213a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org int min_bitrate_kbps; 214a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org if (!codec.GetParam(kCodecParamMinBitrate, &min_bitrate_kbps) || 215a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org min_bitrate_kbps < kMinVideoBitrate) { 216a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org min_bitrate_kbps = kMinVideoBitrate; 2176ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org } 218b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 219a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org int max_bitrate_kbps; 220a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org if (!codec.GetParam(kCodecParamMaxBitrate, &max_bitrate_kbps)) { 221a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org max_bitrate_kbps = 0; 222a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org } 223a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 224a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org return GetSimulcastConfig( 225a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org num_streams, 226a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org GetSimulcastBitrateMode(options), 227a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.width, 228a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.height, 229a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org max_bitrate_kbps * 1000, 230a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org max_qp, 231a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate); 232a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org} 233a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 234f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgstd::vector<webrtc::VideoStream> 235f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoStreams( 236a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoCodec& codec, 237a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org const VideoOptions& options, 238a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org size_t num_streams) { 239a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org if (num_streams != 1) 240a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org return CreateSimulcastVideoStreams(codec, options, num_streams); 241a85307737cc9ea3e79b86daf96d455fca4ad1bb4buildbot@webrtc.org 242d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 243d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 244d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 245d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 24682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate; 247d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 248008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org stream.min_bitrate_bps = kMinVideoBitrate * 1000; 249008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org stream.target_bitrate_bps = stream.max_bitrate_bps = kMaxVideoBitrate * 1000; 250d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 251933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org int max_qp = kDefaultQpMax; 252d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 253d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 254d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 255d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 256d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 257d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 258b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 259f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.orgvoid* WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( 2606f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 2616f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoOptions& options) { 2627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecNameMatches(codec.name, kVp8CodecName)) { 263f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp8 = webrtc::VideoEncoder::GetDefaultVp8Settings(); 264f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org options.video_noise_reduction.Get(&encoder_settings_.vp8.denoisingOn); 265f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp8; 2666f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 267188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org if (CodecNameMatches(codec.name, kVp9CodecName)) { 268f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_settings_.vp9 = webrtc::VideoEncoder::GetDefaultVp9Settings(); 269f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org options.video_noise_reduction.Get(&encoder_settings_.vp9.denoisingOn); 270f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org return &encoder_settings_.vp9; 271188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } 2726f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 2736f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 2746f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 275afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgDefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler() 276afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org : default_recv_ssrc_(0), default_renderer_(NULL) {} 277afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 278afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgUnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc( 279a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org WebRtcVideoChannel2* channel, 280afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org uint32_t ssrc) { 281afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 282afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 283afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDropPacket; 284afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 285afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 286afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org StreamParams sp; 287afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org sp.ssrcs.push_back(ssrc); 288afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 289a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org if (!channel->AddRecvStream(sp, true)) { 290afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Could not create default receive stream."; 291afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 292afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 293afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(ssrc, default_renderer_); 294afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_recv_ssrc_ = ssrc; 295afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDeliverPacket; 296afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 297afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 29842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgWebRtcCallFactory::~WebRtcCallFactory() { 29942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 30042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgwebrtc::Call* WebRtcCallFactory::CreateCall( 30142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org const webrtc::Call::Config& config) { 30242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org return webrtc::Call::Create(config); 30342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 30442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 305afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgVideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { 306afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return default_renderer_; 307afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 308afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 309afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgvoid DefaultUnsignalledSsrcHandler::SetDefaultRenderer( 310afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 311afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoRenderer* renderer) { 312afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_renderer_ = renderer; 313afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { 314afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(default_recv_ssrc_, default_renderer_); 315afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 316afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 317afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 318f1f0d9a4cd53f4eacbf791cb7317612fa7382a45pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2(WebRtcVoiceEngine* voice_engine) 319b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : worker_thread_(NULL), 320f1f0d9a4cd53f4eacbf791cb7317612fa7382a45pbos@webrtc.org voice_engine_(voice_engine), 32182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org default_codec_format_(kDefaultVideoMaxWidth, 32282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org kDefaultVideoMaxHeight, 32382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org FPS_TO_INTERVAL(kDefaultVideoMaxFramerate), 324992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org FOURCC_ANY), 325b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org initialized_(false), 32642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_factory_(&default_call_factory_), 3270a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_(NULL), 3280a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_(NULL) { 329b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; 3307fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 331587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 332587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 333587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpTimestampOffsetHeaderExtensionDefaultId)); 334587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 335587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 336587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 342b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 343b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Terminate(); 344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 345b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 34742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoEngine2::SetCallFactory(WebRtcCallFactory* call_factory) { 3487fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(!initialized_); 34942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_factory_ = call_factory; 35042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 35142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 352d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgbool WebRtcVideoEngine2::Init(rtc::Thread* worker_thread) { 353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org worker_thread_ = worker_thread; 355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(worker_thread_ != NULL); 356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::Terminate() { 362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Terminate"; 363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = false; 365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgint WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } 368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoEncoderConfig& config) { 3718fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org const VideoCodec& codec = config.max_codec; 372957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org bool supports_codec = false; 373957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org for (size_t i = 0; i < video_codecs_.size(); ++i) { 374957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org if (CodecNameMatches(video_codecs_[i].name, codec.name)) { 3752a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].width = codec.width; 3762a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].height = codec.height; 3772a72c6506a49b15d5e079eaa28cb80abb445684bpbos@webrtc.org video_codecs_[i].framerate = codec.framerate; 378957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org supports_codec = true; 379957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org break; 380957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org } 381957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org } 382957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org 383957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org if (!supports_codec) { 384957e802fe0e6e765425955cc1e3e02f73d1a670bpbos@webrtc.org LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported: " 3858fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org << codec.ToString(); 3868fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return false; 3878fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 3888fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 389992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org default_codec_format_ = 390992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org VideoFormat(codec.width, 391992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org codec.height, 392992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org VideoFormat::FpsToInterval(codec.framerate), 393992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org FOURCC_ANY); 394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 395b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 3981ecbe45c7e4c9142896cb2810d699558518f4f28buildbot@webrtc.org const VideoOptions& options, 399b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel) { 4007fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(initialized_); 401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "CreateChannel: " 402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (voice_channel != NULL ? "With" : "Without") 403fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org << " voice channel. Options: " << options.ToString(); 4047fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoChannel2* channel = 4057fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org new WebRtcVideoChannel2(call_factory_, 4063bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org voice_engine_, 4077fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org voice_channel, 408fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options, 4097fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_, 410f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org external_decoder_factory_); 411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!channel->Init()) { 412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete channel; 413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 415e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org channel->SetRecvCodecs(video_codecs_); 416b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return channel; 417b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 418b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 423b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 424b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return rtp_header_extensions_; 426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { 429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Set up logging. 430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; 431b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if min_sev == -1, we keep the current log level. 432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (min_sev < 0) { 433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(min_sev == -1); 434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 4380a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalDecoderFactory( 4390a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoDecoderFactory* decoder_factory) { 4407fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(!initialized_); 4410a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_ = decoder_factory; 4420a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 4430a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 4440a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalEncoderFactory( 4450a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoEncoderFactory* encoder_factory) { 4467fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(!initialized_); 447f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (external_encoder_factory_ == encoder_factory) 448f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org return; 449f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 450f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // No matter what happens we shouldn't hold on to a stale 451f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org // WebRtcSimulcastEncoderFactory. 452f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset(); 453f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org 454f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org if (encoder_factory && 455f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory( 456f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory->codecs())) { 457f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org simulcast_encoder_factory_.reset( 458f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org new WebRtcSimulcastEncoderFactory(encoder_factory)); 459f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org encoder_factory = simulcast_encoder_factory_.get(); 460f18fba2f7b3d1fad7b7b38a9a5dc281bef06c50epbos@webrtc.org } 4610a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_ = encoder_factory; 4627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 4637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org video_codecs_ = GetSupportedCodecs(); 4640a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 4650a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 466b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 471b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 475b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 4768fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 4778fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 4788fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (codec.Matches(in)) { 4798fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 480b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 481b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 483b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 484b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 485b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 486b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// dimensions will be used for aspect ratio matching. 489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 490b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& current, 491b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* out) { 492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(out != NULL); 493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width != requested.height && 495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 496b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // 0xn and nx0 are invalid resolutions. 497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec matching_codec; 501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Codec not supported. 503b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 504b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 505b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 506b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->id = requested.id; 507b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->name = requested.name; 508b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->preference = requested.preference; 509b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 510ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org out->framerate = std::min(requested.framerate, matching_codec.framerate); 511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->feedback_params = requested.feedback_params; 5138fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width = requested.width; 5148fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height = requested.height; 5158fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 5168fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 5178fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 5188fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 5198fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org while (out->width > matching_codec.width) { 5208fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width /= 2; 5218fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height /= 2; 5228fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 5238fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 5248fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return out->width > 0 && out->height > 0; 525b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 529b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 530b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 536b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 537b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 5397fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgstd::vector<VideoCodec> WebRtcVideoEngine2::GetSupportedCodecs() const { 54082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org std::vector<VideoCodec> supported_codecs = DefaultVideoCodecList(); 5417fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5427fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ == NULL) { 5437fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 5447fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 5457fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5467fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs = 5477fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->codecs(); 5487fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 5497fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Don't add internally-supported codecs twice. 5507fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecIsInternallySupported(codecs[i].name)) { 5517fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org continue; 5527fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 5537fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 554d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // External video encoders are given payloads 120-127. This also means that 555d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // we only support up to 8 external payload types. 556d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org const int kExternalVideoPayloadTypeBase = 120; 557d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org size_t payload_type = kExternalVideoPayloadTypeBase + i; 558d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org assert(payload_type < 128); 559d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org VideoCodec codec(static_cast<int>(payload_type), 5607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].name, 5617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_width, 5627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_height, 5637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org codecs[i].max_fps, 5647fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 0); 5657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 5667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AddDefaultFeedbackParams(&codec); 5677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org supported_codecs.push_back(codec); 5687fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 5697fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return supported_codecs; 5707fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 5717fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 57342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org WebRtcCallFactory* call_factory, 5743bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org WebRtcVoiceEngine* voice_engine, 575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel, 576fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org const VideoOptions& options, 5777fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 578f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory) 579b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 5808296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org voice_channel_id_(voice_channel != nullptr 5818296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org ? static_cast<WebRtcVoiceMediaChannel*>( 5828296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org voice_channel)->voe_channel() 5838296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org : -1), 5847fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 585f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org external_decoder_factory_(external_decoder_factory) { 586fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org SetDefaultOptions(); 587fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org options_.SetAll(options); 588b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call::Config config(this); 58942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org config.overuse_callback = this; 5903bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org if (voice_engine != NULL) { 5913bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org config.voice_engine = voice_engine->voe()->engine(); 5923bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org } 593fa553ef6053b20f3768d5fe4314e8c993648bf0apbos@webrtc.org 59442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org call_.reset(call_factory->CreateCall(config)); 595b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 596b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 5996f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 6006f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 6016f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 60242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org options_.cpu_overuse_detection.Set(false); 603d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org options_.dscp.Set(false); 6045ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options_.suspend_below_min_bitrate.Set(false); 60542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org options_.video_noise_reduction.Set(true); 606efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org options_.screencast_min_bitrate.Set(0); 607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 617d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 618b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.begin(); 619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != receive_streams_.end(); 620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 625b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::Init() { return true; } 626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 62796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgbool WebRtcVideoChannel2::CodecIsExternallySupported( 62896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::string& name) const { 62996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_encoder_factory_ == NULL) { 63096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 63196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 63296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 63396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoEncoderFactory::VideoCodec> external_codecs = 63496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_encoder_factory_->codecs(); 63596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t c = 0; c < external_codecs.size(); ++c) { 63696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (CodecNameMatches(name, external_codecs[c].name)) { 63796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return true; 63896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 63996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 64096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 64196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 64296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 64396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 64496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 64596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) 64696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const { 64796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 64896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 64996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodecSettings& codec = mapped_codecs[i]; 65096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (CodecIsInternallySupported(codec.codec.name) || 65196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CodecIsExternallySupported(codec.codec.name)) { 65296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org supported_codecs.push_back(codec); 65396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 65496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 65596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return supported_codecs; 65696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 65796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 65950fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvCodecs"); 660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 66796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without any video codecs."; 668b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 669b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 67196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 67296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org FilterSupportedCodecs(mapped_codecs); 67396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 67496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (mapped_codecs.size() != supported_codecs.size()) { 67596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported video codecs."; 67696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return false; 677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 67996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org recv_codecs_ = supported_codecs; 680d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 681575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 682d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 683d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 684d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 685d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 686d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 687d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 688d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 69350fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendCodecs"); 694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 699b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No video codecs supported by encoder factory."; 704b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 706b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 709a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoCodecSettings old_codec; 710a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (send_codec_.Get(&old_codec) && supported_codecs.front() == old_codec) { 711a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Using same codec, avoid reconfiguring. 712a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 713a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 714a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 715a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org send_codec_.Set(supported_codecs.front()); 716a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 717575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 718d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 719d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 720d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 721d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 722d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org assert(it->second != NULL); 723d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetCodec(supported_codecs.front()); 724d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 725b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 726008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org VideoCodec codec = supported_codecs.front().codec; 727008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org int bitrate_kbps; 728008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) && 729008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 730008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = bitrate_kbps * 1000; 731008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 732008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = 0; 733008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 734008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) && 735008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 736008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = bitrate_kbps * 1000; 737008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 738008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Do not reconfigure start bitrate unless it's specified and positive. 739008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 740008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 741008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) && 742008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_kbps > 0) { 743008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = bitrate_kbps * 1000; 744008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } else { 745008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = -1; 746008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 747008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 748008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org 749b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 750b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 751b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 752b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 753b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodecSettings codec_settings; 754b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 755b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 756b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 757b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 758b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *codec = codec_settings.codec; 759b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 760b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 761b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 762b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, 763b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 764b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 765b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 766575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 767b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 768b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 769b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 770b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 771b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 772b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 773b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRender(bool render) { 774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. 775b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); 776b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 777b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 778b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 779b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 780b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 781b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send && !send_codec_.IsSet()) { 782b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 783b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 784b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 785b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 786b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 787b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 788b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 789b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 790b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 791b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 792b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 793b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 794b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 795b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 796b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sp.ssrcs.empty()) { 797b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No SSRCs in stream parameters."; 798b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 799b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 800b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 801b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 802b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Make sure none of sp.ssrcs are used, not just the identifying 804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ssrc. 805575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 806b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) != send_streams_.end()) { 807a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org LOG(LS_ERROR) << "Send stream with SSRC '" << ssrc << "' already exists."; 808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 8115301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> primary_ssrcs; 8125301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(&primary_ssrcs); 8135301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> rtx_ssrcs; 8145301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(primary_ssrcs, &rtx_ssrcs); 8155301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 8165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_ERROR) 8175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 8185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << sp.ToString(); 819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoSendStream* stream = 8236ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org new WebRtcVideoSendStream(call_.get(), 8247fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_, 8256ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options_, 8265301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_codec_, 8275301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp, 8285301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_rtp_extensions_); 8295301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 830b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 831b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 832b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 833b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 834b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 835b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 836b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 837b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 838b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 839b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 840b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 841b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { 846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 851b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 853b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 855b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 856b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 857b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 858575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org WebRtcVideoSendStream* removed_stream; 859575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org { 860575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 861575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org std::map<uint32, WebRtcVideoSendStream*>::iterator it = 862575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.find(ssrc); 863575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org if (it == send_streams_.end()) { 864575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org return false; 865575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org } 866575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org 867575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org removed_stream = it->second; 868575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org send_streams_.erase(it); 869b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 871575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org delete removed_stream; 872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 873b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 874b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 875b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 876b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 877b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 878b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 879b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 881a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return AddRecvStream(sp, false); 882a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 883a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 884a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp, 885a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream) { 886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); 887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(sp.ssrcs.size() > 0); 888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); // TODO(pbos): Is this ever valid? 891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Check if any of the SSRCs overlap. 893575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 894a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org { 895a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org auto it = receive_streams_.find(ssrc); 896a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org if (it != receive_streams_.end()) { 897a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org if (default_stream || !it->second->IsDefaultStream()) { 898a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org LOG(LS_ERROR) << "Receive stream for SSRC '" << ssrc 899a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org << "' already exists."; 900a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return false; 901a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org } 902a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org delete it->second; 903a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org receive_streams_.erase(it); 904a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org } 905b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 907bd249bc711b3c9efd142eb8de3df489282fe693epbos@webrtc.org webrtc::VideoReceiveStream::Config config; 908d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ConfigureReceiverRtp(&config, sp); 9093bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 9103bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // Set up A/V sync if there is a VoiceChannel. 9113bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // TODO(pbos): The A/V is synched by the receiving channel. So we need to know 9123bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // the SSRC of the remote audio channel in order to sync the correct webrtc 9133bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // VoiceEngine channel. For now sync the first channel in non-conference to 9143bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org // match existing behavior in WebRtcVideoEngine. 9158296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org if (voice_channel_id_ != -1 && receive_streams_.empty() && 9163bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org !options_.conference_mode.GetWithDefaultIfUnset(false)) { 9178296ec518b2659de922668bfe0db57e71eb17e74pbos@webrtc.org config.audio_channel_id = voice_channel_id_; 9183bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org } 9193bf3d238c8c4578e444e5a601684db68c79a29capbos@webrtc.org 920a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org receive_streams_[ssrc] = 921a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org new WebRtcVideoReceiveStream(call_.get(), external_decoder_factory_, 922a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org default_stream, config, recv_codecs_); 923d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 924d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 925d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 926d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 927d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 928d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 929d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const StreamParams& sp) const { 930d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 931d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 932d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remote_ssrc = ssrc; 933d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 934b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 935d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 936257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 937b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 938b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 939b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 940b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 941d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 942d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 943d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 944b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 945d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 946b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 947b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 948b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 949d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 95082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec); 951b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 952b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 95382775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 95482775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org uint32 rtx_ssrc; 95582775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 95682775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 95782775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = 95882775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org config->rtp.rtx[recv_codecs_[i].codec.id]; 95982775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.ssrc = rtx_ssrc; 96082775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org rtx.payload_type = recv_codecs_[i].rtx_payload_type; 96182775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 96282775b13965b4d41299b097c09c30c4ab160cdacandresp@webrtc.org } 963b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 964b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 965b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { 966b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 967b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 968afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 969afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return false; 970b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 971b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 972575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 973d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator stream = 974b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 975b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 976b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 977b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 978b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 979d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org delete stream->second; 980b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 981b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 982b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 983b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 984b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 985b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 986b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 987b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 988b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 989afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_unsignalled_ssrc_handler_.SetDefaultRenderer(this, renderer); 990d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 991b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 992b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 993575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 994d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 995d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 996d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 997d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return false; 998b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 999b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1000b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1001b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1002b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1003b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1004b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { 1005b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1006afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org *renderer = default_unsignalled_ssrc_handler_.GetDefaultRenderer(); 1007afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return *renderer != NULL; 1008b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1009b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1010575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1011d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1012d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1013d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1014b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1015b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1016b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1017b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1018b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1019b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1020058b1f17ac43b1fe69a8c18aaa7999ba88733dfdpbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(VideoMediaInfo* info) { 1021e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info->Clear(); 1022e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillSenderStats(info); 1023e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillReceiverStats(info); 10242b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org webrtc::Call::Stats stats = call_->GetStats(); 10252b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org FillBandwidthEstimationStats(stats, info); 10262b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org if (stats.rtt_ms != -1) { 10272b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org for (size_t i = 0; i < info->senders.size(); ++i) { 10282b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org info->senders[i].rtt_ms = stats.rtt_ms; 10292b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 10302b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org } 1031b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1032b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1033b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1034e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 1035575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1036e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1037e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org send_streams_.begin(); 1038e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != send_streams_.end(); 1039e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1040e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 1041e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1042e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1043e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1044e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 1045575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1046e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1047e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org receive_streams_.begin(); 1048e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != receive_streams_.end(); 1049e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1050e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 1051e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1052e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1053e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1054e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 10552b19f0631233488e891d9db0d170b637dc8fc464pbos@webrtc.org const webrtc::Call::Stats& stats, 1056e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoMediaInfo* video_media_info) { 10570bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo bwe_info; 10580bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_send_bandwidth = stats.send_bandwidth_bps; 10590bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.available_recv_bandwidth = stats.recv_bandwidth_bps; 10600bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info.bucket_delay = stats.pacer_delay_ms; 10610bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 10620bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org // Get send stream bitrate stats. 10630bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 10640bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator stream = 10650bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org send_streams_.begin(); 10660bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stream != send_streams_.end(); 10670bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org ++stream) { 10680bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stream->second->FillBandwidthEstimationInfo(&bwe_info); 10690bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 10700bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org video_media_info->bw_estimations.push_back(bwe_info); 1071e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1072e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1073b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 1074b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1075b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 1076b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1077575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1078b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1079b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1080b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1081b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1082b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetCapturer(capturer); 1083b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1084b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1085b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1086b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1087b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1088b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1089b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1090b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1091b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1092b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1093b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1094b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1095b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1096b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1097b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1098d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1099d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11004e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 11014e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org call_->Receiver()->DeliverPacket( 11024e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()); 11034e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 11044e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 11054e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11064e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 11074e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11084e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 11094e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1111b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = 0; 1113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!GetRtpSsrc(packet->data(), packet->length(), &ssrc)) { 1114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1117a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org // TODO(pbos): Ignore unsignalled packets that don't use the video payload 1118a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org // (prevent creating default receivers for RTX configured as if it would 1119a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org // receive media payloads on those SSRCs). 1120afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 1121afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDropPacket: 1122afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return; 1123afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDeliverPacket: 1124afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org break; 1125afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 1126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 11271e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 11281e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 11291e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1130afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; 1131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1136d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1137d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11381e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 11391e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 11401e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1141b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTCP packet."; 1142b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1143b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1144b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1145b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 114626c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); 114726c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org call_->SignalNetworkState(ready ? webrtc::Call::kNetworkUp 114826c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org : webrtc::Call::kNetworkDown); 1149b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1150b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1151b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { 1152b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1153b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 1154b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1155575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1156b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1157b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1158b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1159b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1160ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org 1161ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org send_streams_[ssrc]->MuteStream(mute); 1162ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org return true; 1163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 116750fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvRtpHeaderExtensions"); 1168587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " 1169587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 11703c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 11713c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1172d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1173c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::vector<webrtc::RtpExtension> filtered_extensions = 1174c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org FilterRtpExtensions(extensions); 1175c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (!RtpExtensionsHaveChanged(recv_rtp_extensions_, filtered_extensions)) 1176c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1177c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1178c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org recv_rtp_extensions_ = filtered_extensions; 1179c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1180575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1181d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1182d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 1183d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 1184d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1185d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 1186d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1188b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1189b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1190b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1191b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 119250fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendRtpHeaderExtensions"); 1193587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " 1194587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 11953c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 11963c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 11973c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1198c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org std::vector<webrtc::RtpExtension> filtered_extensions = 1199c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org FilterRtpExtensions(extensions); 1200c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org if (!RtpExtensionsHaveChanged(send_rtp_extensions_, filtered_extensions)) 1201c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org return true; 1202c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org 1203c37e72e890cb1c769af9006dbd2e582c1a2e2a50pbos@webrtc.org send_rtp_extensions_ = filtered_extensions; 1204a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1205575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1206d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1207d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 1208d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 1209d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1210d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 1211d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1212b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1213b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1214b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1215008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int max_bitrate_bps) { 1216008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org LOG(LS_INFO) << "SetMaxSendBandwidth: " << max_bitrate_bps << "bps."; 1217008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (max_bitrate_bps <= 0) { 1218008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org // Unsetting max bitrate. 1219008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org max_bitrate_bps = -1; 1220008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1221008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.start_bitrate_bps = -1; 1222008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.max_bitrate_bps = max_bitrate_bps; 1223008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org if (max_bitrate_bps > 0 && 1224008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps > max_bitrate_bps) { 1225008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org bitrate_config_.min_bitrate_bps = max_bitrate_bps; 1226008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org } 1227008731868a09e2fe01da53733a612dc24761f791pbos@webrtc.org call_->SetBitrateConfig(bitrate_config_); 1228b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1229b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1230b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1231b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 123250fe359eb614e1bbe41124b9c19263019da0395dpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetOptions"); 1233a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetOptions: " << options.ToString(); 1234a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoOptions old_options = options_; 1235b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 1236a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (options_ == old_options) { 1237a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // No new options to set. 1238a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return true; 1239a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1240d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org rtc::DiffServCodePoint dscp = options_.dscp.GetWithDefaultIfUnset(false) 1241d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org ? rtc::DSCP_AF41 1242d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org : rtc::DSCP_DEFAULT; 1243d819803d4570564a9800a7dd54f4593e6e21a6e7pbos@webrtc.org MediaChannel::SetDscp(dscp); 1244575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 12455301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 12465301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_streams_.begin(); 12475301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it != send_streams_.end(); 12485301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ++it) { 12495301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it->second->SetOptions(options_); 12505301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1251b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1253b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1254b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1255b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1256b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1257b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1258d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Socket::OPT_RCVBUF, 1259b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1260b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1261ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // Speculative change to increase the outbound socket buffer size. 1262ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // In b/15152257, we are seeing a significant number of packets discarded 1263ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // due to lack of socket buffer space, although it's not yet clear what the 1264ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org // ideal value should be. 1265ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1266ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org rtc::Socket::OPT_SNDBUF, 1267ae694effd85d501f15600275dec96522a00c4febbuildbot@webrtc.org kVideoRtpBufferSize); 1268b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1269b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1270b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1271b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1272b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1273b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1274d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(rtc::Message* msg) { 1275b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1276b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1277b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 127842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoChannel2::OnLoadUpdate(Load load) { 1279575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 128042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 128142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org send_streams_.begin(); 128242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org it != send_streams_.end(); 128342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org ++it) { 128442684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org it->second->OnCpuResolutionRequest(load == kOveruse 128542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org ? CoordinatedVideoAdapter::DOWNGRADE 128642684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org : CoordinatedVideoAdapter::UPGRADE); 128742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org } 128842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 128942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 1290b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { 1291d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1292b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendPacket(&packet); 1293b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1294b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1295b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1296d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1297b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendRtcp(&packet); 1298b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1299b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1300b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1301575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1302b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1303b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1304b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1307b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1308b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1309b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1311575d126a3d4a4bf6d43ea07189ac201f6bfe0798pbos@webrtc.org rtc::CritScope stream_lock(&stream_crit_); 1312b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1316b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1317b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1318b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 13206ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 13216ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 13226ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 13236ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 13245301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings) 13255301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org : config(config), options(options), codec_settings(codec_settings) { 13266ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org} 13276ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 1328b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 13307fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org WebRtcVideoEncoderFactory* external_encoder_factory, 13316ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 13325301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings, 13335301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const StreamParams& sp, 13345301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) 1335b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : call_(call), 13367fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_(external_encoder_factory), 1337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 1338b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org parameters_(webrtc::VideoSendStream::Config(), options, codec_settings), 13397fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_(NULL, webrtc::kVideoCodecUnknown, false), 1340b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org capturer_(NULL), 1341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 13429a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org muted_(false), 13439a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org old_adapt_changes_(0) { 13445301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 13455301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13465301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 13475301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 13485301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 13495301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 13505301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 13515301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13525301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings params; 13535301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (codec_settings.Get(¶ms)) { 13545301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodec(params); 13555301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 13605301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 13615301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org call_->DestroyVideoSendStream(stream_); 13625301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 13637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 1364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void CreateBlackFrame(webrtc::I420VideoFrame* video_frame, 1367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1369b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->CreateEmptyFrame(width, height, width, (width + 1) / 2, 1370b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org (width + 1) / 2); 1371b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 16, 1372b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1373b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 128, 1374b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1375b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 128, 1376b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1379b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 138286196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::InputFrame"); 1383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "InputFrame: " << frame->GetWidth() << "x" 1384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << frame->GetHeight(); 1385afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org webrtc::I420VideoFrame video_frame(frame->GetVideoFrameBuffer(), 0, 0, 1386afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org frame->GetVideoRotation()); 1387d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 13885301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ == NULL) { 13895301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_WARNING) << "Capturer inputting frames before send codecs are " 13905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org "configured, dropping."; 13915301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org return; 13925301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 139386196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 139486196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // Not sending, abort early to prevent expensive reconfigurations while 139586196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org // setting up codecs etc. 139686196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (!sending_) 139786196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org return; 139886196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org 1399b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 1400b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(format_.height == 0); 1401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1403b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1404d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org if (muted_) { 1405d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org // Create a black frame to transmit instead. 1406afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org CreateBlackFrame(&video_frame, 1407d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetWidth()), 1408d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org static_cast<int>(frame->GetHeight())); 1409d60d79a14594cbc8266e4a50391ddbe64ed491f0pbos@webrtc.org } 1410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1411c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions( 1412afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org video_frame.width(), video_frame.height(), capturer->IsScreencast()); 1413c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1414af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org LOG(LS_VERBOSE) << "IncomingCapturedFrame: " << video_frame.width() << "x" 1415afdd5dd372d69be7244a3d90d70de9d5ecd60eb9magjed@webrtc.org << video_frame.height() << " -> (codec) " 1416bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org << parameters_.encoder_config.streams.back().width << "x" 1417bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org << parameters_.encoder_config.streams.back().height; 1418af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(video_frame); 1419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1423b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetCapturer"); 1424b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1429d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14319359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (capturer == NULL) { 14329359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (stream_ != NULL) { 14339359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 14349359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org webrtc::I420VideoFrame black_frame; 14359359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org 1436b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org CreateBlackFrame(&black_frame, last_dimensions_.width, 1437b4987bfc24e1e755a6c54053d09a58d1e72228bbpbos@webrtc.org last_dimensions_.height); 1438af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org stream_->Input()->IncomingCapturedFrame(black_frame); 14399359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org } 1440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1444b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1445b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1446b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1460b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1461b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1462d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 14666ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 1469bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.streams.back().max_framerate = 1470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1471c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions(format.width, format.height, false); 1472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1475b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1476b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1477b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1478ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1479d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1480b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1481b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1483b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1484963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org cricket::VideoCapturer* capturer; 1485963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org { 1486963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org rtc::CritScope cs(&lock_); 14879a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ == NULL) 1488963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org return false; 14899a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 14909a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) 14919a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org old_adapt_changes_ += capturer_->video_adapter()->adaptation_changes(); 14929a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 1493963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer = capturer_; 1494963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer_ = NULL; 1495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1496963b979510f6521fd69576f146235c6a5c0f8264pbos@webrtc.org capturer->SignalVideoFrame.disconnect(this); 1497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 15005301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 15015301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1502d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 15035301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings codec_settings; 15045301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (parameters_.codec_settings.Get(&codec_settings)) { 15055301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, options); 15065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } else { 15075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.options = options; 15085301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15095301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 15107fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 1511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 15125301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings) { 1513d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 15145301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 15155301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 15167fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15177fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgwebrtc::VideoCodecType CodecTypeFromName(const std::string& name) { 15187fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (CodecNameMatches(name, kVp8CodecName)) { 15197fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecVP8; 1520188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } else if (CodecNameMatches(name, kVp9CodecName)) { 1521188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return webrtc::kVideoCodecVP9; 15227fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } else if (CodecNameMatches(name, kH264CodecName)) { 15237fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecH264; 15247fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15257fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return webrtc::kVideoCodecUnknown; 15267fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 15277fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15287fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder 15297fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( 15307fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org const VideoCodec& codec) { 15317fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 15327fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15337fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // Do not re-create encoders of the same type. 15347fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { 15357fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return allocated_encoder_; 15367fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15377fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15387fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (external_encoder_factory_ != NULL) { 15397fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder* encoder = 15407fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->CreateVideoEncoder(type); 15417fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder != NULL) { 15427fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(encoder, type, true); 15437fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15447fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15457fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15467fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 15477fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder( 15487fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8), type, false); 1549188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org } else if (type == webrtc::kVideoCodecVP9) { 1550188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org return AllocatedEncoder( 1551188d3b2245b49f21468840386d81b080176b434bandresp@webrtc.org webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp9), type, false); 15527fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15537fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15547fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 15557fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org // support. 15567fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org assert(false); 15577fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org return AllocatedEncoder(NULL, webrtc::kVideoCodecUnknown, false); 15587fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 15597fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15607fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( 15617fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder* encoder) { 15627fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (encoder->external) { 15637fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org external_encoder_factory_->DestroyVideoEncoder(encoder->encoder); 15647fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } else { 15657fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org delete encoder->encoder; 15667fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 15677fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org} 15687fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org 15695301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 15705301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings, 15715301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1572a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org parameters_.encoder_config = 1573a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 157486196c4f481d7f515e54806988f763169e8b9206pbos@webrtc.org if (parameters_.encoder_config.streams.empty()) 1575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1576a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 15775301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 15785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec.height, 1579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 1580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 15816ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15827fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); 15837fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org parameters_.config.encoder_settings.encoder = new_encoder.encoder; 15845301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 15855301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 15865301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 15875301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15885301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org // Set RTX payload type if RTX is enabled. 15895301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 1590b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (codec_settings.rtx_payload_type == -1) { 1591b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 1592b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type. Ignoring."; 1593b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.ssrcs.clear(); 1594b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } else { 1595b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 1596b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 15975301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15985301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15995301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (IsNackEnabled(codec_settings.codec)) { 16005301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.nack.rtp_history_ms = kNackHistoryMs; 16015301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 16025301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 16035ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options.suspend_below_min_bitrate.Get( 16045ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org ¶meters_.config.suspend_below_min_bitrate); 16055ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org 16065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.codec_settings.Set(codec_settings); 16076ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 1608543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 16107fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org if (allocated_encoder_.encoder != new_encoder.encoder) { 16117fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org DestroyVideoEncoder(&allocated_encoder_); 16127fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org allocated_encoder_ = new_encoder; 16137fe1e03dd6da66401010119734245f114bf06645pbos@webrtc.org } 1614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1616d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 1617d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 1618d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1619d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 1620d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1621d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1622d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1623a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgwebrtc::VideoEncoderConfig 1624a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( 1625a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const Dimensions& dimensions, 1626a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const VideoCodec& codec) const { 1627a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config; 1628a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (dimensions.is_screencast) { 1629a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int screencast_min_bitrate_kbps; 1630a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org parameters_.options.screencast_min_bitrate.Get( 1631a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org &screencast_min_bitrate_kbps); 1632a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 1633a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org screencast_min_bitrate_kbps * 1000; 1634a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.content_type = webrtc::VideoEncoderConfig::kScreenshare; 1635a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } else { 1636a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.min_transmit_bitrate_bps = 0; 1637a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.content_type = webrtc::VideoEncoderConfig::kRealtimeVideo; 1638a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1639a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1640a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Restrict dimensions according to codec max. 1641a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int width = dimensions.width; 1642a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org int height = dimensions.height; 1643a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (!dimensions.is_screencast) { 1644a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.width < width) 1645a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org width = codec.width; 1646a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (codec.height < height) 1647a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org height = codec.height; 1648a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1649a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1650a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org VideoCodec clamped_codec = codec; 1651a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.width = width; 1652a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec.height = height; 1653a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1654f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org encoder_config.streams = CreateVideoStreams( 1655a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org clamped_codec, parameters_.options, parameters_.config.rtp.ssrcs.size()); 1656a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1657a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org // Conference mode screencast uses 2 temporal layers split at 100kbit. 1658a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org if (parameters_.options.conference_mode.GetWithDefaultIfUnset(false) && 1659a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org dimensions.is_screencast && encoder_config.streams.size() == 1) { 166046d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault(); 166146d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org 166246d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // For screenshare in conference mode, tl0 and tl1 bitrates are piggybacked 166346d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // on the VideoCodec struct as target and max bitrates, respectively. 166446d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org // See eg. webrtc::VP8EncoderImpl::SetRates(). 166546d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].target_bitrate_bps = 166646d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000; 166746d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org encoder_config.streams[0].max_bitrate_bps = config.tl1_bitrate_kbps * 1000; 1668a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.clear(); 1669a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org encoder_config.streams[0].temporal_layer_thresholds_bps.push_back( 167046d4d29a751c559b6f01b311a1e4aa14a2586a46sprang@webrtc.org config.tl0_bitrate_kbps * 1000); 1671a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org } 1672a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return encoder_config; 1673a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 1674a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1675c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( 1676c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int width, 1677c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int height, 1678efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org bool is_screencast) { 1679efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org if (last_dimensions_.width == width && last_dimensions_.height == height && 1680efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast == is_screencast) { 1681efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org // Configured using the same parameters, do not reconfigure. 1682efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org return; 1683efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org } 1684a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org LOG(LS_INFO) << "SetDimensions: " << width << "x" << height 1685a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org << (is_screencast ? " (screencast)" : " (not screencast)"); 1686efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 1687efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.width = width; 1688efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.height = height; 1689efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org last_dimensions_.is_screencast = is_screencast; 1690efc82c2c734171faba9e400ff60a114e7af2ebccpbos@webrtc.org 1691bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org assert(!parameters_.encoder_config.streams.empty()); 1692c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1693c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org VideoCodecSettings codec_settings; 1694c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 1695c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1696a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config = 1697a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); 1698a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 1699bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = 1700f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org ConfigureVideoEncoderSettings(codec_settings.codec, parameters_.options); 17016f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1702bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); 1703bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 1704bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = NULL; 17056f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 17066f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (!stream_reconfigured) { 1707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 1708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 1709b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1711cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org 1712bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config = encoder_config; 1713b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1714b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1715b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 1716d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 17175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org assert(stream_ != NULL); 1718b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1719b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 1720b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1721b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1722b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 1723d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 17245301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 17255301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org stream_->Stop(); 17265301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1727b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 1728b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1729b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1730e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoSenderInfo 1731e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 1732e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoSenderInfo info; 173377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org webrtc::VideoSendStream::Stats stats; 173477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org { 173577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org rtc::CritScope cs(&lock_); 173677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (uint32_t ssrc : parameters_.config.rtp.ssrcs) 173777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.add_ssrc(ssrc); 173877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 173977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org for (size_t i = 0; i < parameters_.encoder_config.streams.size(); ++i) { 174077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (i == parameters_.encoder_config.streams.size() - 1) { 174177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 174277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].max_bitrate_bps; 174377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } else { 174477e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.preferred_bitrate += 174577e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org parameters_.encoder_config.streams[i].target_bitrate_bps; 174677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 174777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 1748e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 174977e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org if (stream_ == NULL) 175077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org return info; 1751c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org 175277e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org stats = stream_->GetStats(); 175377e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 17549a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes = old_adapt_changes_; 17559a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = CoordinatedVideoAdapter::ADAPTREASON_NONE; 17569a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org 17579a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ != NULL) { 17589a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (!capturer_->IsMuted()) { 17599a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org VideoFormat last_captured_frame_format; 17609a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, &info.effects_frame_drops, 17619a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &info.capturer_frame_time, 17629a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org &last_captured_frame_format); 17639a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 17649a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 17659a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 17669a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_->video_adapter() != nullptr) { 17679a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_changes += capturer_->video_adapter()->adaptation_changes(); 17689a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org info.adapt_reason = capturer_->video_adapter()->adapt_reason(); 17699a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org } 177077e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 177177e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org } 1772e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_input = stats.input_frame_rate; 1773e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 17743e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.avg_encode_ms = stats.avg_encode_time_ms; 17753e6e271ec3253e78ae0eb72156e5236d43f8731dpbos@webrtc.org info.encode_usage_percent = stats.encode_usage_percent; 1776e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 177777e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org info.nominal_bitrate = stats.media_bitrate_bps; 177877e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org 1779273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_width = 0; 1780273a414b0ec2e58fdf3b817ad8b1a02f4ce15287pbos@webrtc.org info.send_frame_height = 0; 178109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 1782e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.substreams.begin(); 178309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 1784e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 178509c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats stream_stats = it->second; 1786cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_sent += stream_stats.rtp_stats.transmitted.payload_bytes + 1787cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.header_bytes + 1788cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stream_stats.rtp_stats.transmitted.padding_bytes; 1789cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_sent += stream_stats.rtp_stats.transmitted.packets; 1790e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 179109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.width > info.send_frame_width) 179209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_width = stream_stats.width; 179309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org if (stream_stats.height > info.send_frame_height) 179409c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.send_frame_height = stream_stats.height; 17951d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_rcvd += stream_stats.rtcp_packet_type_counts.fir_packets; 17961d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_rcvd += stream_stats.rtcp_packet_type_counts.nack_packets; 17971d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_rcvd += stream_stats.rtcp_packet_type_counts.pli_packets; 1798e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1799e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1800e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (!stats.substreams.empty()) { 1801e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 180209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org webrtc::VideoSendStream::StreamStats first_stream_stats = 180309c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org stats.substreams.begin()->second; 1804e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.fraction_lost = 1805e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 1806e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org (1 << 8); 1807e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1808e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1809e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 1810e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1811e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 18120bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo( 18130bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org BandwidthEstimationInfo* bwe_info) { 18140bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org rtc::CritScope cs(&lock_); 18150bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org if (stream_ == NULL) { 18160bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org return; 18170bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 18180bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 181909c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 18200bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org stats.substreams.begin(); 182109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org it != stats.substreams.end(); ++it) { 18220bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->transmit_bitrate += it->second.total_bitrate_bps; 18230bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps; 18240bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org } 1825891d48393e5ccd2f5e03d509c544c00a3d88cbbcpbos@webrtc.org bwe_info->target_enc_bitrate += stats.target_media_bitrate_bps; 182677e11bbe834e3b096db57278d2ad7c76d8c26d66pbos@webrtc.org bwe_info->actual_enc_bitrate += stats.media_bitrate_bps; 18270bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org} 18280bae1fab4adb9bb8164e53142bf419049eafec38stefan@webrtc.org 182942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::OnCpuResolutionRequest( 183042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org CoordinatedVideoAdapter::AdaptRequest adapt_request) { 183142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org rtc::CritScope cs(&lock_); 183242684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org bool adapt_cpu; 183342684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org parameters_.options.cpu_overuse_detection.Get(&adapt_cpu); 18349a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (!adapt_cpu) 183542684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org return; 18369a4410e9934578e84cc129b978a29e151d957994pbos@webrtc.org if (capturer_ == NULL || capturer_->video_adapter() == NULL) 183742684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org return; 183842684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 183942684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org capturer_->video_adapter()->OnCpuResolutionRequest(adapt_request); 184042684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org} 184142684be21b255e2b07eb154e6a2807fa2226167epbos@webrtc.org 1842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 1843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 1844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 1845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 18466ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 18476f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 18486f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 1849bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = 1850f1c8b905204bc7a6c74271ead038f5d80d8d3eedpbos@webrtc.org ConfigureVideoEncoderSettings(codec_settings.codec, parameters_.options); 1851bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 1852b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoSendStream::Config config = parameters_.config; 1853b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { 1854b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 1855b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org "payload type the set codec. Ignoring RTX."; 1856b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org config.rtp.rtx.ssrcs.clear(); 1857b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 1858b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org stream_ = call_->CreateVideoSendStream(config, parameters_.encoder_config); 18596f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1860bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = NULL; 18616f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1862b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 1863b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1864b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1866b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1867d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 1868d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::Call* call, 1869776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org WebRtcVideoDecoderFactory* external_decoder_factory, 1870a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org bool default_stream, 1871d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::VideoReceiveStream::Config& config, 1872d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) 1873d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org : call_(call), 1874d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_(NULL), 1875a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org default_stream_(default_stream), 1876b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org config_(config), 1877776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_(external_decoder_factory), 1878b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org renderer_(NULL), 1879d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_(-1), 1880fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org last_height_(-1), 1881fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_(-1), 1882fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_(0) { 1883d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.renderer = this; 1884d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 1885d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRecvCodecs(recv_codecs); 1886d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1887d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1888d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 1889d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 189096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org ClearDecoders(&allocated_decoders_); 1891d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1892d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 189396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::AllocatedDecoder 189496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder( 189596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* old_decoders, 189696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const VideoCodec& codec) { 189796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 1898776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 189996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < old_decoders->size(); ++i) { 190096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*old_decoders)[i].type == type) { 190196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder decoder = (*old_decoders)[i]; 190296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org (*old_decoders)[i] = old_decoders->back(); 190396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org old_decoders->pop_back(); 190496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return decoder; 190596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 190696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 1907776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 190896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (external_decoder_factory_ != NULL) { 190996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder* decoder = 191096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org external_decoder_factory_->CreateVideoDecoder(type); 191196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (decoder != NULL) { 191296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(decoder, type, true); 191396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 191496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 1915776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 191696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if (type == webrtc::kVideoCodecVP8) { 191796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder( 191896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp8), type, false); 191996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 1920d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1921b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org if (type == webrtc::kVideoCodecVP9) { 1922b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org return AllocatedDecoder( 1923b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp9), type, false); 1924b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org } 1925b9557a9bb7ed5f9aa1e7b3a64de4238572794ae3pbos@webrtc.org 192696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // This shouldn't happen, we should not be trying to create something we don't 192796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // support. 192896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org assert(false); 192996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org return AllocatedDecoder(NULL, webrtc::kVideoCodecUnknown, false); 193096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org} 193196a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 193296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 193396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 193496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder> old_decoders = allocated_decoders_; 193596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.clear(); 193696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.clear(); 193796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < recv_codecs.size(); ++i) { 193896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org AllocatedDecoder allocated_decoder = 193996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org CreateOrReuseVideoDecoder(&old_decoders, recv_codecs[i].codec); 194096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders_.push_back(allocated_decoder); 1941d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 194296a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org webrtc::VideoReceiveStream::Decoder decoder; 194396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.decoder = allocated_decoder.decoder; 194496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_type = recv_codecs[i].codec.id; 194596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org decoder.payload_name = recv_codecs[i].codec.name; 194696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.decoders.push_back(decoder); 194796a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org } 194896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org 194996a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 195096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 1951257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.nack.rtp_history_ms = 1952257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org IsNackEnabled(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 1953257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.remb = IsRembEnabled(recv_codecs.begin()->codec); 1954257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 195596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org ClearDecoders(&old_decoders); 1956d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1957d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1958d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1959d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 1960d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 1961d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.extensions = extensions; 1962d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1963d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1964d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1965d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 1966d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (stream_ != NULL) { 1967d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1968d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1969d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 1970d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_->Start(); 1971d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1972d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 197396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( 197496a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org std::vector<AllocatedDecoder>* allocated_decoders) { 197596a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org for (size_t i = 0; i < allocated_decoders->size(); ++i) { 197696a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org if ((*allocated_decoders)[i].external) { 1977776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org external_decoder_factory_->DestroyVideoDecoder( 197896a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org (*allocated_decoders)[i].decoder); 1979776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } else { 198096a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org delete (*allocated_decoders)[i].decoder; 1981776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 1982776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 198396a93259b361f4b03080a188d781b0835cf4edafpbos@webrtc.org allocated_decoders->clear(); 1984776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org} 1985776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 1986d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 1987d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::I420VideoFrame& frame, 1988d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int time_to_render_ms) { 1989d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1990fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 1991fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (first_frame_timestamp_ < 0) 1992fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_ = frame.timestamp(); 1993fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t rtp_time_elapsed_since_first_frame = 1994fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (timestamp_wraparound_handler_.Unwrap(frame.timestamp()) - 1995fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org first_frame_timestamp_); 1996fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org int64_t elapsed_time_ms = rtp_time_elapsed_since_first_frame / 1997fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org (cricket::kVideoCodecClockrate / 1000); 1998fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org if (frame.ntp_time_ms() > 0) 1999fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org estimated_remote_start_ntp_time_ms_ = frame.ntp_time_ms() - elapsed_time_ms; 2000fc5ad95fecc5ddc7d98dcfbac1c4e75a7814253fmagjed@webrtc.org 2001d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ == NULL) { 2002d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 2003d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return; 2004d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2005d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2006d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 2007d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(frame.width(), frame.height()); 2008d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2009d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2010d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_VERBOSE) << "RenderFrame: (" << frame.width() << "x" << frame.height() 2011d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org << ")"; 2012d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 20132386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org const WebRtcVideoFrame render_frame( 20142386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org frame.video_frame_buffer(), 20152386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org elapsed_time_ms * rtc::kNumNanosecsPerMillisec, 20162386d6dd92f10a715f131b5ad408b1babc1f35b0magjed@webrtc.org frame.render_time_ms() * rtc::kNumNanosecsPerMillisec); 2017d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_->RenderFrame(&render_frame); 2018d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2019d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 20200d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsTextureSupported() const { 20210d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org return true; 20220d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org} 20230d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org 2024a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsDefaultStream() const { 2025a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org return default_stream_; 2026a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org} 2027a2a6fe66a39797ea61a04d80ce3afc494d850bfcpbos@webrtc.org 2028d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 2029d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org cricket::VideoRenderer* renderer) { 2030d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2031d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_ = renderer; 2032d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 2033d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(last_width_, last_height_); 2034d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2035d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2036d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2037d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 2038d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 2039d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // design. 2040d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2041d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return renderer_; 2042d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2043d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2044d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 2045d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int height) { 2046d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 2047d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 2048d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 2049d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 2050d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_ = width; 2051d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_ = height; 2052d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 2053d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 2054e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoReceiverInfo 2055e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 2056e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoReceiverInfo info; 2057e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 2058e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 2059cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.bytes_rcvd = stats.rtp_stats.transmitted.payload_bytes + 2060cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.header_bytes + 2061cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org stats.rtp_stats.transmitted.padding_bytes; 2062cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org info.packets_rcvd = stats.rtp_stats.transmitted.packets; 2063e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2064e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 2065e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 2066e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_output = stats.render_frame_rate; 2067e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 20681d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org { 20691d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org rtc::CritScope frame_cs(&renderer_lock_); 20701d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_width = last_width_; 20711d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.frame_height = last_height_; 20721d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.capture_start_ntp_time_ms = estimated_remote_start_ntp_time_ms_; 20731d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org } 20741d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org 207509c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.decode_ms = stats.decode_ms; 207609c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.max_decode_ms = stats.max_decode_ms; 207709c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.current_delay_ms = stats.current_delay_ms; 207809c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.target_delay_ms = stats.target_delay_ms; 207909c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.jitter_buffer_ms = stats.jitter_buffer_ms; 208009c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.min_playout_delay_ms = stats.min_playout_delay_ms; 208109c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org info.render_delay_ms = stats.render_delay_ms; 208209c77b95bb62566be64da662f0b3b6a838ec6553pbos@webrtc.org 20831d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.firs_sent = stats.rtcp_packet_type_counts.fir_packets; 20841d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.plis_sent = stats.rtcp_packet_type_counts.pli_packets; 20851d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets; 2086e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2087e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 2088e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 2089e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 2090b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 2091b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 2092b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2093a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.orgbool WebRtcVideoChannel2::VideoCodecSettings::operator==( 2094a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2095a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org return codec == other.codec && 2096a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && 2097a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org fec.red_payload_type == other.fec.red_payload_type && 2098a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org rtx_payload_type == other.rtx_payload_type; 2099a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org} 2100a2ef4fe9c331e7668b9e8ff64ce5141a535a5f21pbos@webrtc.org 2101b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 2102b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 2103b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!codecs.empty()); 2104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2105b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 2106b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 2107e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 2108d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org // |rtx_mapping| maps video payload type to rtx payload type. 2109d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org std::map<int, int> rtx_mapping; 2110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2111b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 2112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 2114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 2115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 2116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 2118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 2119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 2120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 2123e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 2124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 2126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 2127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 2128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.red_payload_type == -1); 2129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 2130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 2134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 2135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.ulpfec_payload_type == -1); 2136b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 2137b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2138b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2139b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2140b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 2141b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 2142b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 2143e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org &associated_payload_type) || 2144e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org !IsValidRtpPayloadType(associated_payload_type)) { 2145e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org LOG(LS_ERROR) 2146e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << "RTX codec with invalid or no associated payload type: " 2147e9facf8bb32a1688f2156009c755caa2904e1ac9pkasting@chromium.org << in_codec.ToString(); 2148b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2149b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2150b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 2151b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 2152b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2153b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2154b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 2155b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 2156b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2157b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2158b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 2159b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 2160b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2161b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2162b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 2163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 2164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!video_codecs.empty()); 2165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2166e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 2167e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org it != rtx_mapping.end(); 2168e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org ++it) { 2169e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!payload_used[it->first]) { 2170e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 2171e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2172e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 21738f27fcce79584378da97f0d84574564799e138d6andrew@webrtc.org if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO) { 21748f27fcce79584378da97f0d84574564799e138d6andrew@webrtc.org LOG(LS_ERROR) << "RTX not mapped to regular video codec."; 2175e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 2176e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2177e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 2178e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 2179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Write tests that figure out that I have not verified that RTX 2180b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // codecs aren't mapped to bogus payloads. 2181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 2182b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 21838f27fcce79584378da97f0d84574564799e138d6andrew@webrtc.org if (rtx_mapping[video_codecs[i].codec.id] != 0) { 2184b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 2187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2188b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 2189b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 2190b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2191b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 2192b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 2193b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 2194