187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org/* 287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * libjingle 387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * Copyright 2014 Google Inc. 487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * 587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * Redistribution and use in source and binary forms, with or without 687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * modification, are permitted provided that the following conditions are met: 787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * 887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * this list of conditions and the following disclaimer. 1087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 1187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * this list of conditions and the following disclaimer in the documentation 1287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * and/or other materials provided with the distribution. 1387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * 3. The name of the author may not be used to endorse or promote products 1487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * derived from this software without specific prior written permission. 1587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * 1687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 1787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 1987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org */ 2787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 2887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#ifdef HAVE_WEBRTC_VIDEO 2987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#include "talk/media/webrtc/webrtcvideoengine2.h" 3087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 31d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org#include <set> 3287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#include <string> 3387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 3487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#include "libyuv/convert_from.h" 3587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#include "talk/media/base/videocapturer.h" 3687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#include "talk/media/base/videorenderer.h" 3707a14a70ebfd14b91c5fb61040f02112e0d9c0e7buildbot@webrtc.org#include "talk/media/webrtc/constants.h" 3887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#include "talk/media/webrtc/webrtcvideocapturer.h" 3987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#include "talk/media/webrtc/webrtcvideoframe.h" 4087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#include "talk/media/webrtc/webrtcvoiceengine.h" 41cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/buffer.h" 42cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/logging.h" 43cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/stringutils.h" 4487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#include "webrtc/call.h" 456a97b89328066fe976b587e16034c6d49d98e7fdpbos@webrtc.org#include "webrtc/video_encoder.h" 4687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 4787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#define UNIMPLEMENTED \ 4887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "Call to unimplemented function " << __FUNCTION__; \ 4987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org ASSERT(false) 5087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 5187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgnamespace cricket { 5287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 5387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 5487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// duration hasn't been implemented. 5587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 5687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 57f6cfdbfa66a2ff7cfd93df5d49d6cf624cd80d95buildbot@webrtc.orgstatic const int kDefaultQpMax = 56; 58f6cfdbfa66a2ff7cfd93df5d49d6cf624cd80d95buildbot@webrtc.org 5987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 6087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 6187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstruct VideoCodecPref { 6287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int payload_type; 63d0f3c32952f7ed87c6273de7a75c373a3a42af12pbos@webrtc.org int width; 64d0f3c32952f7ed87c6273de7a75c373a3a42af12pbos@webrtc.org int height; 6587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const char* name; 6687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int rtx_payload_type; 67d0f3c32952f7ed87c6273de7a75c373a3a42af12pbos@webrtc.org} kDefaultVideoCodecPref = {100, 640, 400, kVp8CodecName, 96}; 6887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 69d0f3c32952f7ed87c6273de7a75c373a3a42af12pbos@webrtc.orgVideoCodecPref kRedPref = {116, -1, -1, kRedCodecName, -1}; 70d0f3c32952f7ed87c6273de7a75c373a3a42af12pbos@webrtc.orgVideoCodecPref kUlpfecPref = {117, -1, -1, kUlpfecCodecName, -1}; 7187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 7287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 7387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const VideoCodec& requested_codec, 7487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoCodec* matching_codec) { 7587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 7687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 7787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org *matching_codec = codecs[i]; 7887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 7987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 8087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 8187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 8287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 8387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 84aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.orgstatic void AddDefaultFeedbackParams(VideoCodec* codec) { 85aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org const FeedbackParam kFir(kRtcpFbParamCcm, kRtcpFbCcmParamFir); 86aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org codec->AddFeedbackParam(kFir); 87aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org const FeedbackParam kNack(kRtcpFbParamNack, kParamValueEmpty); 88aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org codec->AddFeedbackParam(kNack); 89aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org const FeedbackParam kPli(kRtcpFbParamNack, kRtcpFbNackParamPli); 90aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org codec->AddFeedbackParam(kPli); 91aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org const FeedbackParam kRemb(kRtcpFbParamRemb, kParamValueEmpty); 92aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org codec->AddFeedbackParam(kRemb); 93aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org} 94aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org 95aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.orgstatic bool IsNackEnabled(const VideoCodec& codec) { 96aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org return codec.HasFeedbackParam( 97aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); 98aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org} 99aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org 10095bea28dc0d19730835d78de995a3c29c8eec4ddpbos@webrtc.orgstatic bool IsRembEnabled(const VideoCodec& codec) { 10195bea28dc0d19730835d78de995a3c29c8eec4ddpbos@webrtc.org return codec.HasFeedbackParam( 10295bea28dc0d19730835d78de995a3c29c8eec4ddpbos@webrtc.org FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); 10395bea28dc0d19730835d78de995a3c29c8eec4ddpbos@webrtc.org} 10495bea28dc0d19730835d78de995a3c29c8eec4ddpbos@webrtc.org 10587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstatic VideoCodec DefaultVideoCodec() { 10687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoCodec default_codec(kDefaultVideoCodecPref.payload_type, 10787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org kDefaultVideoCodecPref.name, 108d0f3c32952f7ed87c6273de7a75c373a3a42af12pbos@webrtc.org kDefaultVideoCodecPref.width, 109d0f3c32952f7ed87c6273de7a75c373a3a42af12pbos@webrtc.org kDefaultVideoCodecPref.height, 11087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org kDefaultFramerate, 11187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 0); 112aa77587108ff0860ec9775b00403171b8ba51371pbos@webrtc.org AddDefaultFeedbackParams(&default_codec); 11387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return default_codec; 11487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 11587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 11687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstatic VideoCodec DefaultRedCodec() { 11787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return VideoCodec(kRedPref.payload_type, kRedPref.name, 0, 0, 0, 0); 11887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 11987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 12087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstatic VideoCodec DefaultUlpfecCodec() { 12187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return VideoCodec(kUlpfecPref.payload_type, kUlpfecPref.name, 0, 0, 0, 0); 12287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 12387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 12487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstatic std::vector<VideoCodec> DefaultVideoCodecs() { 12587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org std::vector<VideoCodec> codecs; 12687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org codecs.push_back(DefaultVideoCodec()); 12787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org codecs.push_back(DefaultRedCodec()); 12887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org codecs.push_back(DefaultUlpfecCodec()); 12987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (kDefaultVideoCodecPref.rtx_payload_type != -1) { 13087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org codecs.push_back( 13187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoCodec::CreateRtxCodec(kDefaultVideoCodecPref.rtx_payload_type, 13287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org kDefaultVideoCodecPref.payload_type)); 13387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 13487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return codecs; 13587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 13687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 137d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.orgstatic bool ValidateRtpHeaderExtensionIds( 138d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 139d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org std::set<int> extensions_used; 140d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 141d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org if (extensions[i].id < 0 || extensions[i].id >= 15 || 142d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org !extensions_used.insert(extensions[i].id).second) { 143d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; 144d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org return false; 145d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org } 146d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org } 147d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org return true; 148d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org} 149d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org 150d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.orgstatic std::vector<webrtc::RtpExtension> FilterRtpExtensions( 151d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 152d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org std::vector<webrtc::RtpExtension> webrtc_extensions; 153d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 154d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org // Unsupported extensions will be ignored. 155d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org if (webrtc::RtpExtension::IsSupported(extensions[i].uri)) { 156d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org webrtc_extensions.push_back(webrtc::RtpExtension( 157d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org extensions[i].uri, extensions[i].id)); 158d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org } else { 159d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; 160d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org } 161d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org } 162d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org return webrtc_extensions; 163d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org} 164d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org 165b931d7ed64da901b09f353355fcc39c8a78e0c28pbos@webrtc.orgWebRtcVideoEncoderFactory2::~WebRtcVideoEncoderFactory2() { 166b931d7ed64da901b09f353355fcc39c8a78e0c28pbos@webrtc.org} 167b931d7ed64da901b09f353355fcc39c8a78e0c28pbos@webrtc.org 168d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.orgstd::vector<webrtc::VideoStream> WebRtcVideoEncoderFactory2::CreateVideoStreams( 169d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org const VideoCodec& codec, 170d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org const VideoOptions& options, 171d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org size_t num_streams) { 172d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org assert(SupportsCodec(codec)); 173d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org if (num_streams != 1) { 174d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org LOG(LS_ERROR) << "Unsupported number of streams: " << num_streams; 175d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org return std::vector<webrtc::VideoStream>(); 176725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org } 17787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 178d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org webrtc::VideoStream stream; 179d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org stream.width = codec.width; 180d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org stream.height = codec.height; 181d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org stream.max_framerate = 182d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultFramerate; 183d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org 184d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org int min_bitrate = kMinVideoBitrate; 185d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org codec.GetParam(kCodecParamMinBitrate, &min_bitrate); 186d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org int max_bitrate = kMaxVideoBitrate; 187d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org codec.GetParam(kCodecParamMaxBitrate, &max_bitrate); 188d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org stream.min_bitrate_bps = min_bitrate * 1000; 189d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate * 1000; 190d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org 191f6cfdbfa66a2ff7cfd93df5d49d6cf624cd80d95buildbot@webrtc.org int max_qp = kDefaultQpMax; 192d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 193d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org stream.max_qp = max_qp; 194d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 195d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org streams.push_back(stream); 196d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org return streams; 197d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org} 19887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 199d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.orgwebrtc::VideoEncoder* WebRtcVideoEncoderFactory2::CreateVideoEncoder( 200d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org const VideoCodec& codec, 201d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org const VideoOptions& options) { 202d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org assert(SupportsCodec(codec)); 203ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2046a97b89328066fe976b587e16034c6d49d98e7fdpbos@webrtc.org return webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8); 205ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org } 206ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org // This shouldn't happen, we should be able to create encoders for all codecs 207ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org // we support. 208ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org assert(false); 209ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org return NULL; 210ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org} 211ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org 212ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.orgvoid* WebRtcVideoEncoderFactory2::CreateVideoEncoderSettings( 213ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org const VideoCodec& codec, 214ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org const VideoOptions& options) { 215ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org assert(SupportsCodec(codec)); 216ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2178f804c79226e998286f4c9e8f5f8ce3918c29654pbos@webrtc.org webrtc::VideoCodecVP8* settings = new webrtc::VideoCodecVP8( 2188f804c79226e998286f4c9e8f5f8ce3918c29654pbos@webrtc.org webrtc::VideoEncoder::GetDefaultVp8Settings()); 219ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org options.video_noise_reduction.Get(&settings->denoisingOn); 220ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org return settings; 221ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org } 222ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org return NULL; 223ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org} 224ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org 225ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.orgvoid WebRtcVideoEncoderFactory2::DestroyVideoEncoderSettings( 226ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org const VideoCodec& codec, 227ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org void* encoder_settings) { 228ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org assert(SupportsCodec(codec)); 229ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org if (encoder_settings == NULL) { 230ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org return; 231ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org } 232ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 233ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org delete reinterpret_cast<webrtc::VideoCodecVP8*>(encoder_settings); 234ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org } 235d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org} 236d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org 237d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.orgbool WebRtcVideoEncoderFactory2::SupportsCodec(const VideoCodec& codec) { 23807a14a70ebfd14b91c5fb61040f02112e0d9c0e7buildbot@webrtc.org return _stricmp(codec.name.c_str(), kVp8CodecName) == 0; 239d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org} 24087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 2419ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.orgDefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler() 2429ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org : default_recv_ssrc_(0), default_renderer_(NULL) {} 2439ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org 2449ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.orgUnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc( 2459ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org VideoMediaChannel* channel, 2469ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org uint32_t ssrc) { 2479ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 2489ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 2499ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org return kDropPacket; 2509ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org } 2519ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org 2529ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org StreamParams sp; 2539ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org sp.ssrcs.push_back(ssrc); 2549ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 2559ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org if (!channel->AddRecvStream(sp)) { 2569ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org LOG(LS_WARNING) << "Could not create default receive stream."; 2579ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org } 2589ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org 2599ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org channel->SetRenderer(ssrc, default_renderer_); 2609ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org default_recv_ssrc_ = ssrc; 2619ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org return kDeliverPacket; 2629ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org} 2639ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org 2649ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.orgVideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { 2659ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org return default_renderer_; 2669ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org} 2679ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org 2689ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.orgvoid DefaultUnsignalledSsrcHandler::SetDefaultRenderer( 2699ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org VideoMediaChannel* channel, 2709ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org VideoRenderer* renderer) { 2719ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org default_renderer_ = renderer; 2729ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org if (default_recv_ssrc_ != 0) { 2739ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org channel->SetRenderer(default_recv_ssrc_, default_renderer_); 2749ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org } 2759ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org} 2769ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org 277d0f3c32952f7ed87c6273de7a75c373a3a42af12pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2() 278faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org : worker_thread_(NULL), 279faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org voice_engine_(NULL), 280faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org video_codecs_(DefaultVideoCodecs()), 2810fbcf962cd3d7148bf77a996c6f31ba4afc99bacbuildbot@webrtc.org default_codec_format_(kDefaultVideoCodecPref.width, 2820fbcf962cd3d7148bf77a996c6f31ba4afc99bacbuildbot@webrtc.org kDefaultVideoCodecPref.height, 2830fbcf962cd3d7148bf77a996c6f31ba4afc99bacbuildbot@webrtc.org FPS_TO_INTERVAL(kDefaultFramerate), 2840fbcf962cd3d7148bf77a996c6f31ba4afc99bacbuildbot@webrtc.org FOURCC_ANY), 285faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org initialized_(false), 286faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org cpu_monitor_(new rtc::CpuMonitor(NULL)), 287d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org channel_factory_(NULL), 288d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org external_decoder_factory_(NULL), 289d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org external_encoder_factory_(NULL) { 290faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; 291f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org rtp_header_extensions_.push_back( 292f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 293f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org kRtpTimestampOffsetHeaderExtensionDefaultId)); 294f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org rtp_header_extensions_.push_back( 295f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 296f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 29787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 29887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 299faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.orgvoid WebRtcVideoEngine2::SetChannelFactory( 300faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org WebRtcVideoChannelFactory* channel_factory) { 301faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org channel_factory_ = channel_factory; 302faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org} 303faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org 30487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 30587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 30687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 30787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (initialized_) { 30887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org Terminate(); 30987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 31087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 31187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 3122a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool WebRtcVideoEngine2::Init(rtc::Thread* worker_thread) { 31387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 31487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org worker_thread_ = worker_thread; 31587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org ASSERT(worker_thread_ != NULL); 31687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 31787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org cpu_monitor_->set_thread(worker_thread_); 31887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (!cpu_monitor_->Start(kCpuMonitorPeriodMs)) { 31987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "Failed to start CPU monitor."; 32087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org cpu_monitor_.reset(); 32187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 32287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 32387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org initialized_ = true; 32487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 32587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 32687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 32787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoEngine2::Terminate() { 32887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Terminate"; 32987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 33087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org cpu_monitor_->Stop(); 33187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 33287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org initialized_ = false; 33387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 33487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 33587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgint WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } 33687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 33787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 33887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const VideoEncoderConfig& config) { 3394c09a710a007655061a0cc34da461897890b905apbos@webrtc.org const VideoCodec& codec = config.max_codec; 3404c09a710a007655061a0cc34da461897890b905apbos@webrtc.org // TODO(pbos): Make use of external encoder factory. 3414c09a710a007655061a0cc34da461897890b905apbos@webrtc.org if (!GetVideoEncoderFactory()->SupportsCodec(codec)) { 3424c09a710a007655061a0cc34da461897890b905apbos@webrtc.org LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported:" 3434c09a710a007655061a0cc34da461897890b905apbos@webrtc.org << codec.ToString(); 3444c09a710a007655061a0cc34da461897890b905apbos@webrtc.org return false; 3454c09a710a007655061a0cc34da461897890b905apbos@webrtc.org } 3464c09a710a007655061a0cc34da461897890b905apbos@webrtc.org 3470fbcf962cd3d7148bf77a996c6f31ba4afc99bacbuildbot@webrtc.org default_codec_format_ = 3480fbcf962cd3d7148bf77a996c6f31ba4afc99bacbuildbot@webrtc.org VideoFormat(codec.width, 3490fbcf962cd3d7148bf77a996c6f31ba4afc99bacbuildbot@webrtc.org codec.height, 3500fbcf962cd3d7148bf77a996c6f31ba4afc99bacbuildbot@webrtc.org VideoFormat::FpsToInterval(codec.framerate), 3510fbcf962cd3d7148bf77a996c6f31ba4afc99bacbuildbot@webrtc.org FOURCC_ANY); 3524c09a710a007655061a0cc34da461897890b905apbos@webrtc.org video_codecs_.clear(); 3534c09a710a007655061a0cc34da461897890b905apbos@webrtc.org video_codecs_.push_back(codec); 35487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 35587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 35687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 35787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgVideoEncoderConfig WebRtcVideoEngine2::GetDefaultEncoderConfig() const { 35887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return VideoEncoderConfig(DefaultVideoCodec()); 35987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 36087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 36187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 36287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VoiceMediaChannel* voice_channel) { 36387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "CreateChannel: " 36487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << (voice_channel != NULL ? "With" : "Without") 36587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << " voice channel."; 36687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org WebRtcVideoChannel2* channel = 36787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org channel_factory_ != NULL 36887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org ? channel_factory_->Create(this, voice_channel) 36987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org : new WebRtcVideoChannel2( 370b931d7ed64da901b09f353355fcc39c8a78e0c28pbos@webrtc.org this, voice_channel, GetVideoEncoderFactory()); 37187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (!channel->Init()) { 37287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org delete channel; 37387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return NULL; 37487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 3752352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org channel->SetRecvCodecs(video_codecs_); 37687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return channel; 37787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 37887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 37987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 38087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return video_codecs_; 38187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 38287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 38387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 38487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 38587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return rtp_header_extensions_; 38687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 38787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 38887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { 38987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Set up logging. 39087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; 39187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // if min_sev == -1, we keep the current log level. 39287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (min_sev < 0) { 39387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(min_sev == -1); 39487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return; 39587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 39687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 39787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 398d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalDecoderFactory( 399d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org WebRtcVideoDecoderFactory* decoder_factory) { 400d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org external_decoder_factory_ = decoder_factory; 401d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org} 402d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org 403d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalEncoderFactory( 404d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org WebRtcVideoEncoderFactory* encoder_factory) { 405d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org if (external_encoder_factory_ == encoder_factory) { 406d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org return; 407d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org } 408d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org if (external_encoder_factory_) { 409d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org external_encoder_factory_->RemoveObserver(this); 410d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org } 411d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org external_encoder_factory_ = encoder_factory; 412d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org if (external_encoder_factory_) { 413d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org external_encoder_factory_->AddObserver(this); 414d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org } 415d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org 416d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org // Invoke OnCodecAvailable() here in case the list of codecs is already 417d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org // available when the encoder factory is installed. If not the encoder 418d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org // factory will invoke the callback later when the codecs become available. 419d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org OnCodecsAvailable(); 420d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org} 421d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org 42287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 42387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 42487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 42587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 42687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 42787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 42887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 42987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 43087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 43187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // with this code (that doesn't ask the factory). 4324c09a710a007655061a0cc34da461897890b905apbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 4334c09a710a007655061a0cc34da461897890b905apbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 4344c09a710a007655061a0cc34da461897890b905apbos@webrtc.org if (codec.Matches(in)) { 4354c09a710a007655061a0cc34da461897890b905apbos@webrtc.org return true; 43687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 43787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 43887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 43987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 44087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 44187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 44287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 44387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 44487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// dimensions will be used for aspect ratio matching. 44587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 44687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const VideoCodec& current, 44787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoCodec* out) { 44887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(out != NULL); 44987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 45087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (requested.width != requested.height && 45187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 45287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // 0xn and nx0 are invalid resolutions. 45387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 45487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 45587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 45687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoCodec matching_codec; 45787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 45887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // Codec not supported. 45987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 46087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 46187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 46287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org out->id = requested.id; 46387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org out->name = requested.name; 46487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org out->preference = requested.preference; 46587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org out->params = requested.params; 46687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org out->framerate = 4672a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::_min(requested.framerate, matching_codec.framerate); 46887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org out->params = requested.params; 46987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org out->feedback_params = requested.feedback_params; 4704c09a710a007655061a0cc34da461897890b905apbos@webrtc.org out->width = requested.width; 4714c09a710a007655061a0cc34da461897890b905apbos@webrtc.org out->height = requested.height; 4724c09a710a007655061a0cc34da461897890b905apbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 4734c09a710a007655061a0cc34da461897890b905apbos@webrtc.org return true; 4744c09a710a007655061a0cc34da461897890b905apbos@webrtc.org } 4754c09a710a007655061a0cc34da461897890b905apbos@webrtc.org 4764c09a710a007655061a0cc34da461897890b905apbos@webrtc.org while (out->width > matching_codec.width) { 4774c09a710a007655061a0cc34da461897890b905apbos@webrtc.org out->width /= 2; 4784c09a710a007655061a0cc34da461897890b905apbos@webrtc.org out->height /= 2; 4794c09a710a007655061a0cc34da461897890b905apbos@webrtc.org } 4804c09a710a007655061a0cc34da461897890b905apbos@webrtc.org 4814c09a710a007655061a0cc34da461897890b905apbos@webrtc.org return out->width > 0 && out->height > 0; 48287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 48387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 48487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoEngine2::SetVoiceEngine(WebRtcVoiceEngine* voice_engine) { 48587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (initialized_) { 48687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_WARNING) << "SetVoiceEngine can not be called after Init"; 48787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 48887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 48987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org voice_engine_ = voice_engine; 49087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 49187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 49287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 49387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 49487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// gotten RTCP info yet from the remote side. 49587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 49687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 49787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 49887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (trace.find(*p) == 0) { 49987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 50087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 50187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 50287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 50387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 50487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 505d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.orgWebRtcVideoEncoderFactory2* WebRtcVideoEngine2::GetVideoEncoderFactory() { 506d2ca8ce545ec2286578cf7a86240b24254e03fdbbuildbot@webrtc.org return &default_video_encoder_factory_; 50787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 50887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 509d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.orgvoid WebRtcVideoEngine2::OnCodecsAvailable() { 510d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org // TODO(pbos): Implement. 511d08c6be2eadc755e14f16ae4ed8dcccf926ab021pbos@webrtc.org} 512725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org// Thin map between VideoFrame and an existing webrtc::I420VideoFrame 51387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// to avoid having to copy the rendered VideoFrame prematurely. 51487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// This implementation is only safe to use in a const context and should never 51587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org// be written to. 516725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.orgclass WebRtcVideoRenderFrame : public VideoFrame { 51787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org public: 51887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org explicit WebRtcVideoRenderFrame(const webrtc::I420VideoFrame* frame) 51987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org : frame_(frame) {} 52087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 52187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual bool InitToBlack(int w, 52287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int h, 52387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org size_t pixel_width, 52487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org size_t pixel_height, 52587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int64 elapsed_time, 52687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int64 time_stamp) OVERRIDE { 52787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org UNIMPLEMENTED; 52887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 52987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 53087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 53187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual bool Reset(uint32 fourcc, 53287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int w, 53387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int h, 53487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int dw, 53587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int dh, 53687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org uint8* sample, 53787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org size_t sample_size, 53887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org size_t pixel_width, 53987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org size_t pixel_height, 54087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int64 elapsed_time, 54187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int64 time_stamp, 54287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int rotation) OVERRIDE { 54387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org UNIMPLEMENTED; 54487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 54587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 54687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 54787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual size_t GetWidth() const OVERRIDE { 54887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return static_cast<size_t>(frame_->width()); 54987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 55087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual size_t GetHeight() const OVERRIDE { 55187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return static_cast<size_t>(frame_->height()); 55287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 55387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 55487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual const uint8* GetYPlane() const OVERRIDE { 55587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return frame_->buffer(webrtc::kYPlane); 55687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 55787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual const uint8* GetUPlane() const OVERRIDE { 55887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return frame_->buffer(webrtc::kUPlane); 55987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 56087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual const uint8* GetVPlane() const OVERRIDE { 56187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return frame_->buffer(webrtc::kVPlane); 56287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 56387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 56487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual uint8* GetYPlane() OVERRIDE { 56587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org UNIMPLEMENTED; 56687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return NULL; 56787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 56887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual uint8* GetUPlane() OVERRIDE { 56987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org UNIMPLEMENTED; 57087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return NULL; 57187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 57287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual uint8* GetVPlane() OVERRIDE { 57387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org UNIMPLEMENTED; 57487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return NULL; 57587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 57687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 57787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual int32 GetYPitch() const OVERRIDE { 57887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return frame_->stride(webrtc::kYPlane); 57987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 58087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual int32 GetUPitch() const OVERRIDE { 58187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return frame_->stride(webrtc::kUPlane); 58287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 58387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual int32 GetVPitch() const OVERRIDE { 58487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return frame_->stride(webrtc::kVPlane); 58587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 58687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 58787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual void* GetNativeHandle() const OVERRIDE { return NULL; } 58887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 58987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual size_t GetPixelWidth() const OVERRIDE { return 1; } 59087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual size_t GetPixelHeight() const OVERRIDE { return 1; } 59187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 59287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual int64 GetElapsedTime() const OVERRIDE { 59387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // Convert millisecond render time to ns timestamp. 5942a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org return frame_->render_time_ms() * rtc::kNumNanosecsPerMillisec; 59587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 59687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual int64 GetTimeStamp() const OVERRIDE { 59787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // Convert 90K rtp timestamp to ns timestamp. 5982a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org return (frame_->timestamp() / 90) * rtc::kNumNanosecsPerMillisec; 59987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 60087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual void SetElapsedTime(int64 elapsed_time) OVERRIDE { UNIMPLEMENTED; } 60187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual void SetTimeStamp(int64 time_stamp) OVERRIDE { UNIMPLEMENTED; } 60287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 60387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual int GetRotation() const OVERRIDE { 60487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org UNIMPLEMENTED; 60587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return ROTATION_0; 60687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 60787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 60887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual VideoFrame* Copy() const OVERRIDE { 60987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org UNIMPLEMENTED; 61087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return NULL; 61187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 61287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 61387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual bool MakeExclusive() OVERRIDE { 61487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org UNIMPLEMENTED; 61587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 61687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 61787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 61887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual size_t CopyToBuffer(uint8* buffer, size_t size) const { 61987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org UNIMPLEMENTED; 62087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return 0; 62187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 62287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 62387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(fbarchard): Refactor into base class and share with LMI 62487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, 62587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org uint8* buffer, 62687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org size_t size, 62787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int stride_rgb) const OVERRIDE { 62887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org size_t width = GetWidth(); 62987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org size_t height = GetHeight(); 63087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org size_t needed = (stride_rgb >= 0 ? stride_rgb : -stride_rgb) * height; 63187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (size < needed) { 63287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_WARNING) << "RGB buffer is not large enough"; 63387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return needed; 63487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 63587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 63687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (libyuv::ConvertFromI420(GetYPlane(), 63787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org GetYPitch(), 63887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org GetUPlane(), 63987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org GetUPitch(), 64087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org GetVPlane(), 64187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org GetVPitch(), 64287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org buffer, 64387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org stride_rgb, 64487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org static_cast<int>(width), 64587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org static_cast<int>(height), 64687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org to_fourcc)) { 64787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "RGB type not supported: " << to_fourcc; 64887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return 0; // 0 indicates error 64987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 65087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return needed; 65187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 65287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 65387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org protected: 65487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org virtual VideoFrame* CreateEmptyFrame(int w, 65587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int h, 65687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org size_t pixel_width, 65787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org size_t pixel_height, 65887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int64 elapsed_time, 65987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int64 time_stamp) const OVERRIDE { 66087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org WebRtcVideoFrame* frame = new WebRtcVideoFrame(); 66187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org frame->InitToBlack( 66287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org w, h, pixel_width, pixel_height, elapsed_time, time_stamp); 66387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return frame; 66487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 66587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 66687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org private: 66787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const webrtc::I420VideoFrame* const frame_; 66887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org}; 66987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 67087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 67187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org WebRtcVideoEngine2* engine, 67287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VoiceMediaChannel* voice_channel, 67387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 674faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 675faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org encoder_factory_(encoder_factory) { 67687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Connect the video and audio with |voice_channel|. 67787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org webrtc::Call::Config config(this); 67887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org Construct(webrtc::Call::Create(config), engine); 67987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 68087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 68187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 68287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org webrtc::Call* call, 68387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org WebRtcVideoEngine2* engine, 68487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 685faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 686faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org encoder_factory_(encoder_factory) { 68787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org Construct(call, engine); 68887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 68987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 69087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::Construct(webrtc::Call* call, 69187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org WebRtcVideoEngine2* engine) { 69287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 69387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org sending_ = false; 69487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org call_.reset(call); 69587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org default_send_ssrc_ = 0; 696ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org 697ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org SetDefaultOptions(); 698ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org} 699ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org 700ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 701ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org options_.video_noise_reduction.Set(true); 7027a0d4a7b261cc6dbcbf57dbd24ca87abfc1c4cacpbos@webrtc.org options_.use_payload_padding.Set(false); 703ec5639581fcefb40c2d49c874f5269c4a0b87616pbos@webrtc.org options_.suspend_below_min_bitrate.Set(false); 70487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 70587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 70687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 70787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 70887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org send_streams_.begin(); 70987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org it != send_streams_.end(); 71087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org ++it) { 71187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org delete it->second; 71287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 71387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 71432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 71587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org receive_streams_.begin(); 71687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org it != receive_streams_.end(); 71787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org ++it) { 71887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org delete it->second; 71987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 72087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 72187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 72287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::Init() { return true; } 72387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 72487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgnamespace { 72587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 72687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstatic std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { 72787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org std::stringstream out; 72887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org out << '{'; 72987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 73087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org out << codecs[i].ToString(); 73187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (i != codecs.size() - 1) { 73287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org out << ", "; 73387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 73487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 73587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org out << '}'; 73687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return out.str(); 73787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 73887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 7392352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.orgstatic bool ValidateCodecFormats(const std::vector<VideoCodec>& codecs) { 7402352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org bool has_video = false; 7412352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 7422352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org if (!codecs[i].ValidateCodecFormat()) { 7432352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org return false; 7442352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org } 7452352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org if (codecs[i].GetCodecType() == VideoCodec::CODEC_VIDEO) { 7462352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org has_video = true; 7472352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org } 7482352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org } 7492352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org if (!has_video) { 7502352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org LOG(LS_ERROR) << "Setting codecs without a video codec is invalid: " 7512352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org << CodecVectorToString(codecs); 7522352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org return false; 7532352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org } 7542352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org return true; 7552352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org} 7562352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org 757f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.orgstatic std::string RtpExtensionsToString( 758f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 759f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org std::stringstream out; 760f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org out << '{'; 761f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 762f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; 763f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org if (i != extensions.size() - 1) { 764f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org out << ", "; 765f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org } 766f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org } 767f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org out << '}'; 768f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org return out.str(); 769f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org} 770f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org 77187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} // namespace 77287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 77387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 77487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 77587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 77687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 77787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 77887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 77987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 78087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (mapped_codecs.empty()) { 78187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without video codec payloads."; 78287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 78387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 78487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 78587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Add a decoder factory which controls supported codecs. 78687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // Blocked on webrtc:2854. 78787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 78807a14a70ebfd14b91c5fb61040f02112e0d9c0e7buildbot@webrtc.org if (_stricmp(mapped_codecs[i].codec.name.c_str(), kVp8CodecName) != 0) { 78987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported codec: '" 79087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << mapped_codecs[i].codec.name << "'"; 79187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 79287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 79387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 79487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 79587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org recv_codecs_ = mapped_codecs; 79632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 79732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 79832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org receive_streams_.begin(); 79932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org it != receive_streams_.end(); 80032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org ++it) { 80132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 80232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org } 80332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 80487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 80587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 80687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 80787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 80887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 80987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 81087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 81187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 81287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 81387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 81487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 81587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 81687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (supported_codecs.empty()) { 81787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "No video codecs supported by encoder factory."; 81887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 81987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 82087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 82187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org send_codec_.Set(supported_codecs.front()); 82287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 82387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 82432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 82532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org send_streams_.begin(); 82632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org it != send_streams_.end(); 82732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org ++it) { 82832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org assert(it->second != NULL); 82932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org it->second->SetCodec(supported_codecs.front()); 83032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org } 83187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 83287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 83387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 83487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 83587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 83687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoCodecSettings codec_settings; 83787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 83887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 83987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 84087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 84187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org *codec = codec_settings.codec; 84287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 84387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 84487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 84587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, 84687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const VideoFormat& format) { 84787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 84887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << format.ToString(); 84987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 85087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 85187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 85287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 85387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 85487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 85587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetRender(bool render) { 85687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. 85787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); 85887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 85987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 86087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 86187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 86287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 86387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (send && !send_codec_.IsSet()) { 86487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 86587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 86687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 86787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (send) { 86887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org StartAllSendStreams(); 86987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } else { 87087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org StopAllSendStreams(); 87187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 87287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org sending_ = send; 87387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 87487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 87587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 87687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 87787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 87887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (sp.ssrcs.empty()) { 87987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "No SSRCs in stream parameters."; 88087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 88187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 88287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 88387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 88487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(ssrc != 0); 88587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Make sure none of sp.ssrcs are used, not just the identifying 88687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // ssrc. 88787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (send_streams_.find(ssrc) != send_streams_.end()) { 88887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "Send stream with ssrc '" << ssrc << "' already exists."; 88987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 89087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 89187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 89261499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org std::vector<uint32> primary_ssrcs; 89361499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org sp.GetPrimarySsrcs(&primary_ssrcs); 89461499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org std::vector<uint32> rtx_ssrcs; 89561499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org sp.GetFidSsrcs(primary_ssrcs, &rtx_ssrcs); 89661499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 89761499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org LOG(LS_ERROR) 89861499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 89961499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org << sp.ToString(); 90087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 90187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 90287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 90387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org WebRtcVideoSendStream* stream = 904725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org new WebRtcVideoSendStream(call_.get(), 90561499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org encoder_factory_, 906725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org options_, 90761499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org send_codec_, 90861499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org sp, 90961499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org send_rtp_extensions_); 91061499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org 91187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org send_streams_[ssrc] = stream; 91287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 91387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 91487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 91587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 91687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (default_send_ssrc_ == 0) { 91787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org default_send_ssrc_ = ssrc; 91887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 91987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (sending_) { 92087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org stream->Start(); 92187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 92287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 92387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 92487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 92587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 92687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { 92787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 92887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 92987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (ssrc == 0) { 93087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (default_send_ssrc_ == 0) { 93187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 93287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 93387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 93487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 93587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 93687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org ssrc = default_send_ssrc_; 93787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 93887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 93987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org std::map<uint32, WebRtcVideoSendStream*>::iterator it = 94087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org send_streams_.find(ssrc); 94187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (it == send_streams_.end()) { 94287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 94387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 94487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 94587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org delete it->second; 94687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org send_streams_.erase(it); 94787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 94887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (ssrc == default_send_ssrc_) { 94987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org default_send_ssrc_ = 0; 95087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 95187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 95287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 95387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 95487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 95587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 95687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); 95787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(sp.ssrcs.size() > 0); 95887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 95987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 96087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(ssrc != 0); // TODO(pbos): Is this ever valid? 96187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 96287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Check if any of the SSRCs overlap. 96387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (receive_streams_.find(ssrc) != receive_streams_.end()) { 96487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "Receive stream for SSRC " << ssrc << "already exists."; 96587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 96687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 96787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 968fdd800a7edaa11fd431cea1ed673e991a746e63bpbos@webrtc.org webrtc::VideoReceiveStream::Config config; 96932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org ConfigureReceiverRtp(&config, sp); 97032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org receive_streams_[ssrc] = 97132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org new WebRtcVideoReceiveStream(call_.get(), config, recv_codecs_); 97232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 97332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org return true; 97432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org} 97532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 97632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 97732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 97832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org const StreamParams& sp) const { 97932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 98032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 98132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config->rtp.remote_ssrc = ssrc; 98232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 98387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 98432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 98595bea28dc0d19730835d78de995a3c29c8eec4ddpbos@webrtc.org 98687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 98787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 98887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 98987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // (receive-only) or know a good local SSRC. 99032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 99132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 99232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 99387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } else { 99432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 99587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 99687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 99787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 99832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 99932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org if (recv_codecs_[i].codec.id == kDefaultVideoCodecPref.payload_type) { 100032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config->rtp.fec = recv_codecs_[i].fec; 100132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org uint32 rtx_ssrc; 100232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 100332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 100432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].ssrc = rtx_ssrc; 100532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].payload_type = 100632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org recv_codecs_[i].rtx_payload_type; 100787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 100832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org break; 100987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 101087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 101187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 101287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 101387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 101487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { 101587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 101687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (ssrc == 0) { 10179ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 10189ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org return false; 101987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 102087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 102132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator stream = 102287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org receive_streams_.find(ssrc); 102387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (stream == receive_streams_.end()) { 102487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 102587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 102687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 102732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org delete stream->second; 102887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org receive_streams_.erase(stream); 102987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 103087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 103187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 103287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 103387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 103487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 103587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 103687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (ssrc == 0) { 10379ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org default_unsignalled_ssrc_handler_.SetDefaultRenderer(this, renderer); 103832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org return true; 103987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 104087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 104132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 104232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org receive_streams_.find(ssrc); 104332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org if (it == receive_streams_.end()) { 104432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org return false; 104587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 104687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 104787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org it->second->SetRenderer(renderer); 104887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 104987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 105087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 105187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { 105287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (ssrc == 0) { 10539ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org *renderer = default_unsignalled_ssrc_handler_.GetDefaultRenderer(); 10549ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org return *renderer != NULL; 105587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 105687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 105732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 105832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org receive_streams_.find(ssrc); 105932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org if (it == receive_streams_.end()) { 106087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 106187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 106287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org *renderer = it->second->GetRenderer(); 106387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 106487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 106587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 106687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(const StatsOptions& options, 106787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoMediaInfo* info) { 10687724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info->Clear(); 10697724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org FillSenderStats(info); 10707724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org FillReceiverStats(info); 10717724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org FillBandwidthEstimationStats(info); 107287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 107387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 107487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 10757724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 10767724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 10777724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org send_streams_.begin(); 10787724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org it != send_streams_.end(); 10797724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org ++it) { 10807724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 10817724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org } 10827724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org} 10837724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 10847724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 10857724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 10867724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org receive_streams_.begin(); 10877724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org it != receive_streams_.end(); 10887724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org ++it) { 10897724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 10907724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org } 10917724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org} 10927724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 10937724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 10947724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org VideoMediaInfo* video_media_info) { 10957724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org // TODO(pbos): Implement. 10967724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org} 10977724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 109887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 109987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 110087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 110187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(ssrc != 0); 110287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 110387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 110487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 110587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 110687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return send_streams_[ssrc]->SetCapturer(capturer); 110787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 110887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 110987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 111087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Implement. 111187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 111287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 111387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 111487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 111587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 111687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Implement. 111787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 111887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 111987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 112087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 112187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 11222a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Buffer* packet, 11232a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11248ed4b07ccb4b81b9618ff3e66c8e7fe6707e4a7cpbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 11258ed4b07ccb4b81b9618ff3e66c8e7fe6707e4a7cpbos@webrtc.org call_->Receiver()->DeliverPacket( 11268ed4b07ccb4b81b9618ff3e66c8e7fe6707e4a7cpbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()); 11278ed4b07ccb4b81b9618ff3e66c8e7fe6707e4a7cpbos@webrtc.org switch (delivery_result) { 11288ed4b07ccb4b81b9618ff3e66c8e7fe6707e4a7cpbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 11298ed4b07ccb4b81b9618ff3e66c8e7fe6707e4a7cpbos@webrtc.org return; 11308ed4b07ccb4b81b9618ff3e66c8e7fe6707e4a7cpbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 11318ed4b07ccb4b81b9618ff3e66c8e7fe6707e4a7cpbos@webrtc.org return; 11328ed4b07ccb4b81b9618ff3e66c8e7fe6707e4a7cpbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 11338ed4b07ccb4b81b9618ff3e66c8e7fe6707e4a7cpbos@webrtc.org break; 113487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 113587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 113687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org uint32 ssrc = 0; 113787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (!GetRtpSsrc(packet->data(), packet->length(), &ssrc)) { 113887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return; 113987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 114087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 11419ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org // TODO(pbos): Make sure that the unsignalled SSRC uses the video payload. 11429ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org // Also figure out whether RTX needs to be handled. 11439ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 11449ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org case UnsignalledSsrcHandler::kDropPacket: 11459ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org return; 11469ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org case UnsignalledSsrcHandler::kDeliverPacket: 11479ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org break; 11489ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org } 114987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 1150175d728c5742d83af7a30f4d21077e540d705ac0pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 1151175d728c5742d83af7a30f4d21077e540d705ac0pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 1152175d728c5742d83af7a30f4d21077e540d705ac0pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 11539ebf75e35979cec9a6e7330e6ac3fe1caeaf0302pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; 115487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return; 115587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 115687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 115787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 115887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 11592a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Buffer* packet, 11602a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketTime& packet_time) { 1161175d728c5742d83af7a30f4d21077e540d705ac0pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 1162175d728c5742d83af7a30f4d21077e540d705ac0pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 1163175d728c5742d83af7a30f4d21077e540d705ac0pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 116487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTCP packet."; 116587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 116687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 116787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 116887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 11695f2d3eac8887e8814441f898cd08ce5c8135c18dpbos@webrtc.org LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); 11705f2d3eac8887e8814441f898cd08ce5c8135c18dpbos@webrtc.org call_->SignalNetworkState(ready ? webrtc::Call::kNetworkUp 11715f2d3eac8887e8814441f898cd08ce5c8135c18dpbos@webrtc.org : webrtc::Call::kNetworkDown); 117287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 117387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 117487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { 117587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 117687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << (mute ? "mute" : "unmute"); 117787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(ssrc != 0); 117887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 117987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 118087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 118187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 1182ba39a2fa6de680dd8b3b9ec548ebc06f9683ced3pbos@webrtc.org 1183ba39a2fa6de680dd8b3b9ec548ebc06f9683ced3pbos@webrtc.org send_streams_[ssrc]->MuteStream(mute); 1184ba39a2fa6de680dd8b3b9ec548ebc06f9683ced3pbos@webrtc.org return true; 118587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 118687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 118787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 118887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1189f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " 1190f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org << RtpExtensionsToString(extensions); 1191d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 1192d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org return false; 119332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 1194d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org recv_rtp_extensions_ = FilterRtpExtensions(extensions); 119532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 119632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org receive_streams_.begin(); 119732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org it != receive_streams_.end(); 119832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org ++it) { 119932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 120032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org } 120187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 120287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 120387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 120487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 120587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1206f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " 1207f0150cc22727b9ecda7a3433e5ea9672711bec64pbos@webrtc.org << RtpExtensionsToString(extensions); 1208d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 1209d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org return false; 1210d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org 1211d7058ccf68063d7b08c584a696cf8629c7c12dffpbos@webrtc.org send_rtp_extensions_ = FilterRtpExtensions(extensions); 121232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 121332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org send_streams_.begin(); 121432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org it != send_streams_.end(); 121532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org ++it) { 121632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 121732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org } 121887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 121987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 122087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 122187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetStartSendBandwidth(int bps) { 122287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Implement. 122387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "SetStartSendBandwidth: " << bps; 122487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 122587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 122687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 122787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int bps) { 122887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Implement. 122987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "SetMaxSendBandwidth: " << bps; 123087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 123187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 123287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 123387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 123487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); 123587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org options_.SetAll(options); 123661499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 123761499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org send_streams_.begin(); 123861499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org it != send_streams_.end(); 123961499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org ++it) { 124061499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org it->second->SetOptions(options_); 124161499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org } 124287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 124387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 124487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 124587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 124687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org MediaChannel::SetInterface(iface); 124787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 124887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 12492a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Socket::OPT_RCVBUF, 125087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org kVideoRtpBufferSize); 125187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 125287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(sriniv): Remove or re-enable this. 125387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // As part of b/8030474, send-buffer is size now controlled through 125487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // portallocator flags. 125587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // network_interface_->SetOption(NetworkInterface::ST_RTP, 12562a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org // rtc::Socket::OPT_SNDBUF, 125787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // kVideoRtpBufferSize); 125887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 125987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 126087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 126187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Implement. 126287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 126387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 12642a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(rtc::Message* msg) { 126587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // Ignored. 126687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 126787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 126887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { 12692a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 127087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return MediaChannel::SendPacket(&packet); 127187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 127287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 127387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 12742a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 127587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return MediaChannel::SendRtcp(&packet); 127687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 127787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 127887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 127987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 128087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org send_streams_.begin(); 128187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org it != send_streams_.end(); 128287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org ++it) { 128387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org it->second->Start(); 128487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 128587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 128687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 128787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 128887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 128987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org send_streams_.begin(); 129087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org it != send_streams_.end(); 129187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org ++it) { 129287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org it->second->Stop(); 129387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 129487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 129587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 1296725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 1297725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org VideoSendStreamParameters( 1298725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org const webrtc::VideoSendStream::Config& config, 1299725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org const VideoOptions& options, 130061499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings) 130161499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org : config(config), options(options), codec_settings(codec_settings) { 1302725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org} 1303725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org 130487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 130587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org webrtc::Call* call, 130661499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory, 1307725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org const VideoOptions& options, 130861499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings, 130961499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org const StreamParams& sp, 131061499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) 131187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org : call_(call), 131287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org encoder_factory_(encoder_factory), 131387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org stream_(NULL), 1314faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org parameters_(webrtc::VideoSendStream::Config(), options, codec_settings), 1315faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org capturer_(NULL), 131687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org sending_(false), 131761499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org muted_(false) { 131861499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 131961499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org 132061499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 132161499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 132261499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 132361499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 132461499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 132561499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org 132661499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org VideoCodecSettings params; 132761499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org if (codec_settings.Get(¶ms)) { 132861499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org SetCodec(params); 132961499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org } 133087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 133187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 133287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 133387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org DisconnectCapturer(); 133461499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org if (stream_ != NULL) { 133561499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org call_->DestroyVideoSendStream(stream_); 133661499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org } 1337725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org delete parameters_.config.encoder_settings.encoder; 133887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 133987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 134087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstatic void SetWebRtcFrameToBlack(webrtc::I420VideoFrame* video_frame) { 134187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(video_frame != NULL); 134287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 134387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 16, 134487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 134587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 134687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 128, 134787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 134887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 134987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 128, 135087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 135187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 135287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 135387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstatic void CreateBlackFrame(webrtc::I420VideoFrame* video_frame, 135487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int width, 135587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int height) { 135687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org video_frame->CreateEmptyFrame( 135787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org width, height, width, (width + 1) / 2, (width + 1) / 2); 135887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org SetWebRtcFrameToBlack(video_frame); 135987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 136087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 136187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstatic void ConvertToI420VideoFrame(const VideoFrame& frame, 136287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org webrtc::I420VideoFrame* i420_frame) { 136387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org i420_frame->CreateFrame( 136487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org static_cast<int>(frame.GetYPitch() * frame.GetHeight()), 136587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org frame.GetYPlane(), 136687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org static_cast<int>(frame.GetUPitch() * ((frame.GetHeight() + 1) / 2)), 136787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org frame.GetUPlane(), 136887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org static_cast<int>(frame.GetVPitch() * ((frame.GetHeight() + 1) / 2)), 136987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org frame.GetVPlane(), 137087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org static_cast<int>(frame.GetWidth()), 137187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org static_cast<int>(frame.GetHeight()), 137287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org static_cast<int>(frame.GetYPitch()), 137387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org static_cast<int>(frame.GetUPitch()), 137487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org static_cast<int>(frame.GetVPitch())); 137587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 137687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 137787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 137887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoCapturer* capturer, 137987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const VideoFrame* frame) { 138087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "InputFrame: " << frame->GetWidth() << "x" 138187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << frame->GetHeight(); 138287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // Lock before copying, can be called concurrently when swapping input source. 13832a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope frame_cs(&frame_lock_); 138447740f2c26aea1b3b7830abdcba063a12a61d009pbos@webrtc.org ConvertToI420VideoFrame(*frame, &video_frame_); 138547740f2c26aea1b3b7830abdcba063a12a61d009pbos@webrtc.org 13862a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&lock_); 138761499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org if (stream_ == NULL) { 138861499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org LOG(LS_WARNING) << "Capturer inputting frames before send codecs are " 138961499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org "configured, dropping."; 139061499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org return; 139161499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org } 139287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (format_.width == 0) { // Dropping frames. 139387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(format_.height == 0); 139487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 139587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return; 139687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 139747740f2c26aea1b3b7830abdcba063a12a61d009pbos@webrtc.org if (muted_) { 139847740f2c26aea1b3b7830abdcba063a12a61d009pbos@webrtc.org // Create a black frame to transmit instead. 139947740f2c26aea1b3b7830abdcba063a12a61d009pbos@webrtc.org CreateBlackFrame(&video_frame_, 140047740f2c26aea1b3b7830abdcba063a12a61d009pbos@webrtc.org static_cast<int>(frame->GetWidth()), 140147740f2c26aea1b3b7830abdcba063a12a61d009pbos@webrtc.org static_cast<int>(frame->GetHeight())); 140247740f2c26aea1b3b7830abdcba063a12a61d009pbos@webrtc.org } 140387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // Reconfigure codec if necessary. 1404baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org SetDimensions( 1405baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org video_frame_.width(), video_frame_.height(), capturer->IsScreencast()); 1406baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org 140787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "SwapFrame: " << video_frame_.width() << "x" 140887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << video_frame_.height() << " -> (codec) " 1409ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org << parameters_.encoder_config.streams.back().width << "x" 1410ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org << parameters_.encoder_config.streams.back().height; 141187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org stream_->Input()->SwapFrame(&video_frame_); 141287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 141387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 141487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 141587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoCapturer* capturer) { 141687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 141787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 141887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 141987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 142087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org { 14212a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&lock_); 142287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 1423fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org if (capturer == NULL) { 1424fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org if (stream_ != NULL) { 1425fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 1426fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org webrtc::I420VideoFrame black_frame; 1427fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org 1428fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org int width = format_.width; 1429fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org int height = format_.height; 1430fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org int half_width = (width + 1) / 2; 1431fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org black_frame.CreateEmptyFrame( 1432fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org width, height, width, half_width, half_width); 1433fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org SetWebRtcFrameToBlack(&black_frame); 1434baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org SetDimensions(width, height, false); 1435fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org stream_->Input()->SwapFrame(&black_frame); 1436fbfc394ffc0d57d37f983b0cee170742b4c46cc6pbos@webrtc.org } 143787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 143887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org capturer_ = NULL; 143987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 144087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 144187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 144287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org capturer_ = capturer; 144387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 144487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 144587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // violations. 144687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 144787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 144887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 144987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 145087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 145187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const VideoFormat& format) { 145287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if ((format.width == 0 || format.height == 0) && 145387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org format.width != format.height) { 145487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 145587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org "both, 0x0 drops frames)."; 145687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 145787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 145887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 14592a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&lock_); 146087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (format.width == 0 && format.height == 0) { 146187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_INFO) 146287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 1463725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 146487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } else { 146587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 1466ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org parameters_.encoder_config.streams.back().max_framerate = 146787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1468baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org SetDimensions(format.width, format.height, false); 146987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 147087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 147187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org format_ = format; 147287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 147387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 147487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 1475ba39a2fa6de680dd8b3b9ec548ebc06f9683ced3pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 14762a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&lock_); 147787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org muted_ = mute; 147887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 147987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 148087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 14812a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&lock_); 148287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (capturer_ == NULL) { 148387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 148487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 148587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org capturer_->SignalVideoFrame.disconnect(this); 148687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org capturer_ = NULL; 148787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 148887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 148987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 149061499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 149161499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org const VideoOptions& options) { 14922a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&lock_); 149361499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org VideoCodecSettings codec_settings; 149461499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org if (parameters_.codec_settings.Get(&codec_settings)) { 149561499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org SetCodecAndOptions(codec_settings, options); 149661499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org } else { 149761499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org parameters_.options = options; 149861499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org } 149961499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org} 150087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 150161499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org const VideoCodecSettings& codec_settings) { 15022a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&lock_); 150361499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 150461499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org} 150561499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 150661499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org const VideoCodecSettings& codec_settings, 150761499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org const VideoOptions& options) { 1508725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org std::vector<webrtc::VideoStream> video_streams = 1509725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org encoder_factory_->CreateVideoStreams( 151061499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org codec_settings.codec, options, parameters_.config.rtp.ssrcs.size()); 1511725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org if (video_streams.empty()) { 151287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return; 151387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 1514ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org parameters_.encoder_config.streams = video_streams; 151561499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 151661499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org codec_settings.codec.height, 151787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoFormat::FpsToInterval(30), 151887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org FOURCC_I420); 1519725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org 1520725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org webrtc::VideoEncoder* old_encoder = 1521725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org parameters_.config.encoder_settings.encoder; 1522725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org parameters_.config.encoder_settings.encoder = 152361499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org encoder_factory_->CreateVideoEncoder(codec_settings.codec, options); 152461499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 152561499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 152661499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 152761499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org 152861499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org // Set RTX payload type if RTX is enabled. 152961499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 153061499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 15317a0d4a7b261cc6dbcbf57dbd24ca87abfc1c4cacpbos@webrtc.org 15327a0d4a7b261cc6dbcbf57dbd24ca87abfc1c4cacpbos@webrtc.org options.use_payload_padding.Get( 15337a0d4a7b261cc6dbcbf57dbd24ca87abfc1c4cacpbos@webrtc.org ¶meters_.config.rtp.rtx.pad_with_redundant_payloads); 153461499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org } 153561499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org 153661499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org if (IsNackEnabled(codec_settings.codec)) { 153761499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org parameters_.config.rtp.nack.rtp_history_ms = kNackHistoryMs; 153861499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org } 153961499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org 1540ec5639581fcefb40c2d49c874f5269c4a0b87616pbos@webrtc.org options.suspend_below_min_bitrate.Get( 1541ec5639581fcefb40c2d49c874f5269c4a0b87616pbos@webrtc.org ¶meters_.config.suspend_below_min_bitrate); 1542ec5639581fcefb40c2d49c874f5269c4a0b87616pbos@webrtc.org 154361499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org parameters_.codec_settings.Set(codec_settings); 1544725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org parameters_.options = options; 15457a0d4a7b261cc6dbcbf57dbd24ca87abfc1c4cacpbos@webrtc.org 154687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org RecreateWebRtcStream(); 154787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org delete old_encoder; 154887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 154987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 155032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 155132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 15522a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&lock_); 155332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 155432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org RecreateWebRtcStream(); 155532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org} 155632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 1557baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( 1558baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org int width, 1559baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org int height, 1560baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org bool override_max) { 1561ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org assert(!parameters_.encoder_config.streams.empty()); 156287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height; 1563baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org 1564baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org VideoCodecSettings codec_settings; 1565baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 1566baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org // Restrict dimensions according to codec max. 1567baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org if (!override_max) { 1568baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org if (codec_settings.codec.width < width) 1569baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org width = codec_settings.codec.width; 1570baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org if (codec_settings.codec.height < height) 1571baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org height = codec_settings.codec.height; 1572baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org } 1573baa196a1777c920c593110d6bafeea8bf9282de3pbos@webrtc.org 1574ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org if (parameters_.encoder_config.streams.back().width == width && 1575ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org parameters_.encoder_config.streams.back().height == height) { 157687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return; 157787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 157887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 1579ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config = parameters_.encoder_config; 1580ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org encoder_config.encoder_specific_settings = 1581ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org encoder_factory_->CreateVideoEncoderSettings(codec_settings.codec, 1582ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org parameters_.options); 1583ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org 158443d397ff84588095360214c8dcda7254028b7456pbos@webrtc.org VideoCodec codec = codec_settings.codec; 158543d397ff84588095360214c8dcda7254028b7456pbos@webrtc.org codec.width = width; 158643d397ff84588095360214c8dcda7254028b7456pbos@webrtc.org codec.height = height; 158743d397ff84588095360214c8dcda7254028b7456pbos@webrtc.org 1588ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org encoder_config.streams = encoder_factory_->CreateVideoStreams( 1589ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org codec, parameters_.options, parameters_.config.rtp.ssrcs.size()); 1590ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org 1591ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); 1592ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org 1593ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings( 1594ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org codec_settings.codec, 1595ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org encoder_config.encoder_specific_settings); 1596ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org 1597ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org encoder_config.encoder_specific_settings = NULL; 1598ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org 1599ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org if (!stream_reconfigured) { 160087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 160187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << width << "x" << height; 160287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return; 160387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 160443d397ff84588095360214c8dcda7254028b7456pbos@webrtc.org 1605ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org parameters_.encoder_config = encoder_config; 160687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 160787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 160887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 16092a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&lock_); 161061499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org assert(stream_ != NULL); 161187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org stream_->Start(); 161287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org sending_ = true; 161387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 161487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 161587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 16162a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&lock_); 161761499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org if (stream_ != NULL) { 161861499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org stream_->Stop(); 161961499560dd39b9d4050c4fac2054ce76daa185cfpbos@webrtc.org } 162087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org sending_ = false; 162187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 162287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 16237724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.orgVideoSenderInfo 16247724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 16257724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org VideoSenderInfo info; 16262a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&lock_); 16277724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org for (size_t i = 0; i < parameters_.config.rtp.ssrcs.size(); ++i) { 16287724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.add_ssrc(parameters_.config.rtp.ssrcs[i]); 16297724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org } 16307724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 163193d0f92d0811b4fd4f87431018d5631a546bb334pbos@webrtc.org if (stream_ == NULL) { 163293d0f92d0811b4fd4f87431018d5631a546bb334pbos@webrtc.org return info; 163393d0f92d0811b4fd4f87431018d5631a546bb334pbos@webrtc.org } 163493d0f92d0811b4fd4f87431018d5631a546bb334pbos@webrtc.org 16357724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 16367724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.framerate_input = stats.input_frame_rate; 16377724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 16387724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 16397724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org for (std::map<uint32_t, webrtc::StreamStats>::iterator it = 16407724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org stats.substreams.begin(); 16417724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org it != stats.substreams.end(); 16427724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org ++it) { 16437724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 16447724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org webrtc::StreamStats stream_stats = it->second; 16457724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.bytes_sent += stream_stats.rtp_stats.bytes + 16467724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org stream_stats.rtp_stats.header_bytes + 16477724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org stream_stats.rtp_stats.padding_bytes; 16487724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.packets_sent += stream_stats.rtp_stats.packets; 16497724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 16507724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org } 16517724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 16527724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org if (!stats.substreams.empty()) { 16537724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 16547724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org webrtc::StreamStats first_stream_stats = stats.substreams.begin()->second; 16557724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.fraction_lost = 16567724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 16577724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org (1 << 8); 16587724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org } 16597724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 16607724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org if (capturer_ != NULL && !capturer_->IsMuted()) { 16617724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org VideoFormat last_captured_frame_format; 16627724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, 16637724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org &info.effects_frame_drops, 16647724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org &info.capturer_frame_time, 16657724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org &last_captured_frame_format); 16667724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 16677724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 16687724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.send_frame_width = 1669ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org static_cast<int>(parameters_.encoder_config.streams.front().width); 16707724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.send_frame_height = 1671ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org static_cast<int>(parameters_.encoder_config.streams.front().height); 16727724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org } 16737724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 16747724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org // TODO(pbos): Support or remove the following stats. 16757724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.packets_cached = -1; 16767724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.rtt_ms = -1; 16777724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 16787724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org return info; 16797724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org} 16807724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 168187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 168287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (stream_ != NULL) { 168387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org call_->DestroyVideoSendStream(stream_); 168487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 1685725448760ec749e62f2a3843a491c278599d1963pbos@webrtc.org 1686ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org VideoCodecSettings codec_settings; 1687ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 1688ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = 1689ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org encoder_factory_->CreateVideoEncoderSettings(codec_settings.codec, 1690ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org parameters_.options); 1691ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org 1692ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org stream_ = call_->CreateVideoSendStream(parameters_.config, 1693ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org parameters_.encoder_config); 1694ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org 1695ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings( 1696ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org codec_settings.codec, 1697ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings); 1698ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org 1699ce453652c492556c3b22dcf37df975ed2c3daba1pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = NULL; 1700ccce52e7cc31c93e49ba32f84d83d7b88e74051apbos@webrtc.org 170187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (sending_) { 170287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org stream_->Start(); 170387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 170487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 170587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 170632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 170732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org webrtc::Call* call, 170832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org const webrtc::VideoReceiveStream::Config& config, 170932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) 171032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org : call_(call), 171132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org stream_(NULL), 1712faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org config_(config), 1713faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org renderer_(NULL), 171432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org last_width_(-1), 1715faebccea1be83ffdc22d9d084dd4dfa132b5e02epbos@webrtc.org last_height_(-1) { 171632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config_.renderer = this; 171732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 171832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org SetRecvCodecs(recv_codecs); 171932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org} 172032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 172132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 172232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 172332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org} 172432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 172532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 172632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 172732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 172832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org // TODO(pbos): Base receive codecs off recv_codecs_ and set up using a 172932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org // DecoderFactory similar to send side. Pending webrtc:2854. 173032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org // Also set up default codecs if there's nothing in recv_codecs_. 173132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org webrtc::VideoCodec codec; 173232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org memset(&codec, 0, sizeof(codec)); 173332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 173432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org codec.plType = kDefaultVideoCodecPref.payload_type; 173532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org strcpy(codec.plName, kDefaultVideoCodecPref.name); 173632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org codec.codecType = webrtc::kVideoCodecVP8; 173732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org codec.codecSpecific.VP8.resilience = webrtc::kResilientStream; 173832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org codec.codecSpecific.VP8.numberOfTemporalLayers = 1; 173932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org codec.codecSpecific.VP8.denoisingOn = true; 174032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org codec.codecSpecific.VP8.errorConcealmentOn = false; 174132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org codec.codecSpecific.VP8.automaticResizeOn = false; 174232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org codec.codecSpecific.VP8.frameDroppingOn = true; 174332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org codec.codecSpecific.VP8.keyFrameInterval = 3000; 174432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org // Bitrates don't matter and are ignored for the receiver. This is put in to 174532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org // have the current underlying implementation accept the VideoCodec. 174632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org codec.minBitrate = codec.startBitrate = codec.maxBitrate = 300; 174732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config_.codecs.clear(); 174832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config_.codecs.push_back(codec); 174932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 175032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 175132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 175295bea28dc0d19730835d78de995a3c29c8eec4ddpbos@webrtc.org config_.rtp.nack.rtp_history_ms = 175395bea28dc0d19730835d78de995a3c29c8eec4ddpbos@webrtc.org IsNackEnabled(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 175495bea28dc0d19730835d78de995a3c29c8eec4ddpbos@webrtc.org config_.rtp.remb = IsRembEnabled(recv_codecs.begin()->codec); 175595bea28dc0d19730835d78de995a3c29c8eec4ddpbos@webrtc.org 175632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org RecreateWebRtcStream(); 175732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org} 175832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 175932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 176032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 176132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org config_.rtp.extensions = extensions; 176232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org RecreateWebRtcStream(); 176332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org} 176432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 176532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 176632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org if (stream_ != NULL) { 176732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 176832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org } 176932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 177032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org stream_->Start(); 177132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org} 177232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 177332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 177432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org const webrtc::I420VideoFrame& frame, 177532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org int time_to_render_ms) { 17762a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 177732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org if (renderer_ == NULL) { 177832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 177932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org return; 178032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org } 178132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 178232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 178332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org SetSize(frame.width(), frame.height()); 178432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org } 178532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 178632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org LOG(LS_VERBOSE) << "RenderFrame: (" << frame.width() << "x" << frame.height() 178732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org << ")"; 178832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 178932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org const WebRtcVideoRenderFrame render_frame(&frame); 179032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org renderer_->RenderFrame(&render_frame); 179132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org} 179232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 179332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 179432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org cricket::VideoRenderer* renderer) { 17952a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 179632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org renderer_ = renderer; 179732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 179832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org SetSize(last_width_, last_height_); 179932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org } 180032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org} 180132723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 180232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 180332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 180432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org // design. 18052a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 180632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org return renderer_; 180732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org} 180832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 180932723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 181032723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org int height) { 18112a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 181232723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 181332723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 181432723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org } 181532723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org last_width_ = width; 181632723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org last_height_ = height; 181732723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org} 181832723567bade6a7ee1198fba34a4d04374c96359pbos@webrtc.org 18197724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.orgVideoReceiverInfo 18207724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 18217724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org VideoReceiverInfo info; 18227724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 18237724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 18247724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.bytes_rcvd = stats.rtp_stats.bytes + stats.rtp_stats.header_bytes + 18257724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org stats.rtp_stats.padding_bytes; 18267724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.packets_rcvd = stats.rtp_stats.packets; 18277724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 18287724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 18297724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 18307724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.framerate_output = stats.render_frame_rate; 18317724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 18322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope frame_cs(&renderer_lock_); 18337724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.frame_width = last_width_; 18347724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.frame_height = last_height_; 18357724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 18367724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org // TODO(pbos): Support or remove the following stats. 18377724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org info.packets_concealed = -1; 18387724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 18397724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org return info; 18407724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org} 18417724e69fe70bdcd448f171353d326d378f03be6bpbos@webrtc.org 184287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 184387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org : rtx_payload_type(-1) {} 184487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 184587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 184687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 184787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(!codecs.empty()); 184887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 184987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 185087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org std::map<int, bool> payload_used; 18512352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 185287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org std::map<int, int> rtx_mapping; // video payload type -> rtx payload type. 185387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 185487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org webrtc::FecConfig fec_settings; 185587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 185687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 185787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 185887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int payload_type = in_codec.id; 185987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 186087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (payload_used[payload_type]) { 186187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 186287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << in_codec.ToString(); 186387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return std::vector<VideoCodecSettings>(); 186487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 186587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org payload_used[payload_type] = true; 18662352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 186787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 186887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org switch (in_codec.GetCodecType()) { 186987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org case VideoCodec::CODEC_RED: { 187087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // RED payload type, should not have duplicates. 187187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(fec_settings.red_payload_type == -1); 187287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 187387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org continue; 187487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 187587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 187687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 187787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // ULPFEC payload type, should not have duplicates. 187887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(fec_settings.ulpfec_payload_type == -1); 187987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 188087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org continue; 188187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 188287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 188387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org case VideoCodec::CODEC_RTX: { 188487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int associated_payload_type; 188587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 188687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org &associated_payload_type)) { 188787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "RTX codec without associated payload type: " 188887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org << in_codec.ToString(); 188987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return std::vector<VideoCodecSettings>(); 189087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 189187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 189287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org continue; 189387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 189487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 189587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org case VideoCodec::CODEC_VIDEO: 189687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org break; 189787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 189887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 189987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 190087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org video_codecs.back().codec = in_codec; 190187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 190287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 190387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 190487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // parameters into this code is a logic error. 190587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org assert(!video_codecs.empty()); 190687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 19072352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 19082352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org it != rtx_mapping.end(); 19092352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org ++it) { 19102352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org if (!payload_used[it->first]) { 19112352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 19122352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org return std::vector<VideoCodecSettings>(); 19132352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org } 19142352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO) { 19152352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org LOG(LS_ERROR) << "RTX not mapped to regular video codec."; 19162352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org return std::vector<VideoCodecSettings>(); 19172352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org } 19182352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org } 19192352cb302a3c072473044373f1792624b61bba4bpbos@webrtc.org 192087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // TODO(pbos): Write tests that figure out that I have not verified that RTX 192187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // codecs aren't mapped to bogus payloads. 192287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 192387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org video_codecs[i].fec = fec_settings; 192487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (rtx_mapping[video_codecs[i].codec.id] != 0) { 192587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 192687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 192787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 192887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 192987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return video_codecs; 193087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 193187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 193287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 193387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 193487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) { 193587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 193687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 193787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (encoder_factory_->SupportsCodec(mapped_codecs[i].codec)) { 193887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org supported_codecs.push_back(mapped_codecs[i]); 193987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 194087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 194187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return supported_codecs; 194287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 194387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 194487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} // namespace cricket 194587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 194687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 1947