webrtcvideoengine2.cc revision c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2
1b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org/* 2b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * libjingle 3b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Copyright 2014 Google Inc. 4b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 5b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Redistribution and use in source and binary forms, with or without 6b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * modification, are permitted provided that the following conditions are met: 7b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 8b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 9b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * this list of conditions and the following disclaimer. 10b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 11b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * this list of conditions and the following disclaimer in the documentation 12b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * and/or other materials provided with the distribution. 13b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 3. The name of the author may not be used to endorse or promote products 14b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * derived from this software without specific prior written permission. 15b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 16b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org */ 27b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 28b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#ifdef HAVE_WEBRTC_VIDEO 29b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoengine2.h" 30b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 313c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org#include <set> 32b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include <string> 33b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 34b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "libyuv/convert_from.h" 35d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/buffer.h" 36d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/logging.h" 37d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/stringutils.h" 38b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videocapturer.h" 39b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videorenderer.h" 40df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org#include "talk/media/webrtc/constants.h" 41b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideocapturer.h" 42b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoframe.h" 43b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvoiceengine.h" 44b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/call.h" 45b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// TODO(pbos): Move codecs out of modules (webrtc:3070). 46b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" 47b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 48b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#define UNIMPLEMENTED \ 49b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Call to unimplemented function " << __FUNCTION__; \ 50b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(false) 51b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 52b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace cricket { 53b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 54b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 55b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// duration hasn't been implemented. 56b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 57b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 58b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 59b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 60b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstruct VideoCodecPref { 61b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type; 62b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const char* name; 63b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rtx_payload_type; 64df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org} kDefaultVideoCodecPref = {100, kVp8CodecName, 96}; 65b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 66b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoCodecPref kRedPref = {116, kRedCodecName, -1}; 67b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoCodecPref kUlpfecPref = {117, kUlpfecCodecName, -1}; 68b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 69b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// The formats are sorted by the descending order of width. We use the order to 70b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// find the next format for CPU and bandwidth adaptation. 718fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.orgconst VideoFormatPod kDefaultMaxVideoFormat = { 72b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 640, 400, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}; 73b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 74b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 75b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& requested_codec, 76b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* matching_codec) { 77b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 78b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 79b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *matching_codec = codecs[i]; 80b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 81b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 82b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 83b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 84b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 85b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 86f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.orgstatic void AddDefaultFeedbackParams(VideoCodec* codec) { 87f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kFir(kRtcpFbParamCcm, kRtcpFbCcmParamFir); 88f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kFir); 89f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kNack(kRtcpFbParamNack, kParamValueEmpty); 90f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kNack); 91f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kPli(kRtcpFbParamNack, kRtcpFbNackParamPli); 92f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kPli); 93f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kRemb(kRtcpFbParamRemb, kParamValueEmpty); 94f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kRemb); 95f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org} 96f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org 97f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.orgstatic bool IsNackEnabled(const VideoCodec& codec) { 98f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org return codec.HasFeedbackParam( 99f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); 100f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org} 101f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org 102257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.orgstatic bool IsRembEnabled(const VideoCodec& codec) { 103257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org return codec.HasFeedbackParam( 104257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); 105257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org} 106257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultVideoCodec() { 108b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec default_codec(kDefaultVideoCodecPref.payload_type, 109b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.name, 1108fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org kDefaultMaxVideoFormat.width, 1118fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org kDefaultMaxVideoFormat.height, 112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultFramerate, 113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 0); 114f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org AddDefaultFeedbackParams(&default_codec); 115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return default_codec; 116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultRedCodec() { 119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kRedPref.payload_type, kRedPref.name, 0, 0, 0, 0); 120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultUlpfecCodec() { 123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kUlpfecPref.payload_type, kUlpfecPref.name, 0, 0, 0, 0); 124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic std::vector<VideoCodec> DefaultVideoCodecs() { 127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodec> codecs; 128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultVideoCodec()); 129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultRedCodec()); 130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultUlpfecCodec()); 131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (kDefaultVideoCodecPref.rtx_payload_type != -1) { 132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back( 133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec::CreateRtxCodec(kDefaultVideoCodecPref.rtx_payload_type, 134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.payload_type)); 135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 136b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return codecs; 137b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 138b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1393c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic bool ValidateRtpHeaderExtensionIds( 1403c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1413c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::set<int> extensions_used; 1423c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1433c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (extensions[i].id < 0 || extensions[i].id >= 15 || 1443c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org !extensions_used.insert(extensions[i].id).second) { 1453c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; 1463c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1473c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1483c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1493c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return true; 1503c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 1513c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1523c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic std::vector<webrtc::RtpExtension> FilterRtpExtensions( 1533c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1543c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::vector<webrtc::RtpExtension> webrtc_extensions; 1553c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1563c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org // Unsupported extensions will be ignored. 1573c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (webrtc::RtpExtension::IsSupported(extensions[i].uri)) { 1583c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org webrtc_extensions.push_back(webrtc::RtpExtension( 1593c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org extensions[i].uri, extensions[i].id)); 1603c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } else { 1613c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; 1623c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1633c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1643c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return webrtc_extensions; 1653c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 1663c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1670d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.orgWebRtcVideoEncoderFactory2::~WebRtcVideoEncoderFactory2() { 1680d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org} 1690d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org 170d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgstd::vector<webrtc::VideoStream> WebRtcVideoEncoderFactory2::CreateVideoStreams( 171d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 172d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 173d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 174d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org assert(SupportsCodec(codec)); 175d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org if (num_streams != 1) { 176d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org LOG(LS_ERROR) << "Unsupported number of streams: " << num_streams; 177d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return std::vector<webrtc::VideoStream>(); 1786ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org } 179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 180d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 181d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 182d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 183d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 184d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultFramerate; 185d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 186d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int min_bitrate = kMinVideoBitrate; 187d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMinBitrate, &min_bitrate); 188d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int max_bitrate = kMaxVideoBitrate; 189d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxBitrate, &max_bitrate); 190d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.min_bitrate_bps = min_bitrate * 1000; 191d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate * 1000; 192d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 193d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int max_qp = 56; 194d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 195d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 196d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 197d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 198d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 199d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 200b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 201d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgwebrtc::VideoEncoder* WebRtcVideoEncoderFactory2::CreateVideoEncoder( 202d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 203d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options) { 204d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org assert(SupportsCodec(codec)); 2056f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2066f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return webrtc::VP8Encoder::Create(); 2076f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2086f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org // This shouldn't happen, we should be able to create encoders for all codecs 2096f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org // we support. 2106f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(false); 2116f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 2126f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 2136f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2146f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid* WebRtcVideoEncoderFactory2::CreateVideoEncoderSettings( 2156f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 2166f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoOptions& options) { 2176f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(SupportsCodec(codec)); 2186f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2196f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org webrtc::VideoCodecVP8* settings = new webrtc::VideoCodecVP8(); 2206f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->resilience = webrtc::kResilientStream; 2216f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->numberOfTemporalLayers = 1; 2226f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org options.video_noise_reduction.Get(&settings->denoisingOn); 2236f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->errorConcealmentOn = false; 2246f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->automaticResizeOn = false; 2256f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->frameDroppingOn = true; 2266f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->keyFrameInterval = 3000; 2276f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return settings; 2286f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2296f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 2306f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 2316f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2326f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoEncoderFactory2::DestroyVideoEncoderSettings( 2336f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 2346f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org void* encoder_settings) { 2356f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(SupportsCodec(codec)); 2366f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (encoder_settings == NULL) { 2376f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return; 2386f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2396f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2406f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2416f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org delete reinterpret_cast<webrtc::VideoCodecVP8*>(encoder_settings); 2426f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return; 2436f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2446f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org // We should be able to destroy all encoder settings we've allocated. 2456f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(false); 246d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 247d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 248d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgbool WebRtcVideoEncoderFactory2::SupportsCodec(const VideoCodec& codec) { 249df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org return _stricmp(codec.name.c_str(), kVp8CodecName) == 0; 250d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 251b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2() { 253b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Construct without a factory or voice engine. 254d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org Construct(NULL, NULL, new rtc::CpuMonitor(NULL)); 255b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 256b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 257b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2( 258b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoChannelFactory* channel_factory) { 259b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Construct without a voice engine. 260d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org Construct(channel_factory, NULL, new rtc::CpuMonitor(NULL)); 261b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 262b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 263b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::Construct(WebRtcVideoChannelFactory* channel_factory, 264b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVoiceEngine* voice_engine, 265d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CpuMonitor* cpu_monitor) { 266b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2"; 267b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org worker_thread_ = NULL; 268b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org voice_engine_ = voice_engine; 269b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = false; 270b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capture_started_ = false; 271b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_.reset(cpu_monitor); 272b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org channel_factory_ = channel_factory; 273b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 274b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs_ = DefaultVideoCodecs(); 2758fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org default_codec_format_ = VideoFormat(kDefaultMaxVideoFormat); 276587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org 277587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 278587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 279587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpTimestampOffsetHeaderExtensionDefaultId)); 280587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 281587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 282587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 283b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 284b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 285b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 286b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 287b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 288b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 289b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Terminate(); 290b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 291b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 292b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 293d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgbool WebRtcVideoEngine2::Init(rtc::Thread* worker_thread) { 294b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 295b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org worker_thread_ = worker_thread; 296b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(worker_thread_ != NULL); 297b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 298b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->set_thread(worker_thread_); 299b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!cpu_monitor_->Start(kCpuMonitorPeriodMs)) { 300b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Failed to start CPU monitor."; 301b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_.reset(); 302b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 303b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 304b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 307b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 308b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::Terminate() { 309b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Terminate"; 310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 311b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->Stop(); 312b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = false; 314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 316b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgint WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } 317b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 318b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetOptions(const VideoOptions& options) { 319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Do we need this? This is a no-op in the existing 320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // WebRtcVideoEngine implementation. 321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); 322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // options_ = options; 323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoEncoderConfig& config) { 3288fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org const VideoCodec& codec = config.max_codec; 3298fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org // TODO(pbos): Make use of external encoder factory. 3308fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (!GetVideoEncoderFactory()->SupportsCodec(codec)) { 3318fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported:" 3328fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org << codec.ToString(); 3338fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return false; 3348fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 3358fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 3368fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org default_codec_format_ = 3378fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoFormat(codec.width, 3388fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org codec.height, 3398fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoFormat::FpsToInterval(codec.framerate), 3408fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org FOURCC_ANY); 3418fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org video_codecs_.clear(); 3428fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org video_codecs_.push_back(codec); 343b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 345b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoEncoderConfig WebRtcVideoEngine2::GetDefaultEncoderConfig() const { 347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoEncoderConfig(DefaultVideoCodec()); 348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel) { 352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "CreateChannel: " 353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (voice_channel != NULL ? "With" : "Without") 354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << " voice channel."; 355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoChannel2* channel = 356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org channel_factory_ != NULL 357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ? channel_factory_->Create(this, voice_channel) 358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : new WebRtcVideoChannel2( 3590d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org this, voice_channel, GetVideoEncoderFactory()); 360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!channel->Init()) { 361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete channel; 362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 364e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org channel->SetRecvCodecs(video_codecs_); 365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return channel; 366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 374b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return rtp_header_extensions_; 375b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { 378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Set up logging. 379b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; 380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if min_sev == -1, we keep the current log level. 381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (min_sev < 0) { 382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(min_sev == -1); 383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 387b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 388b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 389b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 390b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 391b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 392b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetLocalRenderer(VideoRenderer* renderer) { 393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement or remove. Unclear which stream should be rendered 394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // locally even. 395b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 398b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 399b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 400b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 4038fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 4048fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 4058fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (codec.Matches(in)) { 4068fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 409b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 415b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// dimensions will be used for aspect ratio matching. 416b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 417b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& current, 418b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* out) { 419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(out != NULL); 420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width != requested.height && 422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 423b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // 0xn and nx0 are invalid resolutions. 424b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec matching_codec; 428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Codec not supported. 430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 431b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->id = requested.id; 434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->name = requested.name; 435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->preference = requested.preference; 436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->framerate = 438d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::_min(requested.framerate, matching_codec.framerate); 439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->feedback_params = requested.feedback_params; 4418fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width = requested.width; 4428fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height = requested.height; 4438fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 4448fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 4458fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 4468fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 4478fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org while (out->width > matching_codec.width) { 4488fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width /= 2; 4498fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height /= 2; 4508fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 4518fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 4528fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return out->width > 0 && out->height > 0; 453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetVoiceEngine(WebRtcVoiceEngine* voice_engine) { 456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "SetVoiceEngine can not be called after Init"; 458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 460b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org voice_engine_ = voice_engine; 461b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 462b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 466b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 471b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 475b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 476d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgWebRtcVideoEncoderFactory2* WebRtcVideoEngine2::GetVideoEncoderFactory() { 477d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return &default_video_encoder_factory_; 478b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 479b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 4806ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org// Thin map between VideoFrame and an existing webrtc::I420VideoFrame 481b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// to avoid having to copy the rendered VideoFrame prematurely. 482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This implementation is only safe to use in a const context and should never 483b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be written to. 4846ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgclass WebRtcVideoRenderFrame : public VideoFrame { 485b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org public: 486b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org explicit WebRtcVideoRenderFrame(const webrtc::I420VideoFrame* frame) 487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : frame_(frame) {} 488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool InitToBlack(int w, 490b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 491b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) OVERRIDE { 495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 496b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool Reset(uint32 fourcc, 500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int w, 501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dw, 503b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dh, 504b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* sample, 505b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t sample_size, 506b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 507b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 508b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 509b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp, 510b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rotation) OVERRIDE { 511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 513b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 514b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 515b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetWidth() const OVERRIDE { 516b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->width()); 517b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 518b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetHeight() const OVERRIDE { 519b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->height()); 520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 522b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetYPlane() const OVERRIDE { 523b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kYPlane); 524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 525b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetUPlane() const OVERRIDE { 526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kUPlane); 527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetVPlane() const OVERRIDE { 529b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kVPlane); 530b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetYPlane() OVERRIDE { 533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 536b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetUPlane() OVERRIDE { 537b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 539b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 540b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetVPlane() OVERRIDE { 541b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 542b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 543b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 544b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 545b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetYPitch() const OVERRIDE { 546b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kYPlane); 547b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetUPitch() const OVERRIDE { 549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kUPlane); 550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetVPitch() const OVERRIDE { 552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kVPlane); 553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 554b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void* GetNativeHandle() const OVERRIDE { return NULL; } 556b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 557b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelWidth() const OVERRIDE { return 1; } 558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelHeight() const OVERRIDE { return 1; } 559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 560b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetElapsedTime() const OVERRIDE { 561b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert millisecond render time to ns timestamp. 562d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org return frame_->render_time_ms() * rtc::kNumNanosecsPerMillisec; 563b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 564b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetTimeStamp() const OVERRIDE { 565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert 90K rtp timestamp to ns timestamp. 566d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org return (frame_->timestamp() / 90) * rtc::kNumNanosecsPerMillisec; 567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetElapsedTime(int64 elapsed_time) OVERRIDE { UNIMPLEMENTED; } 569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetTimeStamp(int64 time_stamp) OVERRIDE { UNIMPLEMENTED; } 570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int GetRotation() const OVERRIDE { 572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return ROTATION_0; 574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* Copy() const OVERRIDE { 577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 581b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool MakeExclusive() OVERRIDE { 582b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 583b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 584b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 585b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 586b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t CopyToBuffer(uint8* buffer, size_t size) const { 587b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 588b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; 589b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 590b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 591b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(fbarchard): Refactor into base class and share with LMI 592b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, 593b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* buffer, 594b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t size, 595b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int stride_rgb) const OVERRIDE { 596b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t width = GetWidth(); 597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t height = GetHeight(); 598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t needed = (stride_rgb >= 0 ? stride_rgb : -stride_rgb) * height; 599b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (size < needed) { 600b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "RGB buffer is not large enough"; 601b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 602b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (libyuv::ConvertFromI420(GetYPlane(), 605b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetYPitch(), 606b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPlane(), 607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPitch(), 608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPlane(), 609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPitch(), 610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org buffer, 611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stride_rgb, 612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(width), 613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(height), 614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org to_fourcc)) { 615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RGB type not supported: " << to_fourcc; 616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; // 0 indicates error 617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 618b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org protected: 622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* CreateEmptyFrame(int w, 623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 625b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 627b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) const OVERRIDE { 628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Remove WebRtcVideoFrame dependency, and have a non-const 629b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // version of I420VideoFrame wrapped. 630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoFrame* frame = new WebRtcVideoFrame(); 631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame->InitToBlack( 632b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org w, h, pixel_width, pixel_height, elapsed_time, time_stamp); 633b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame; 634b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 635b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 636b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org private: 637b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const webrtc::I420VideoFrame* const frame_; 638b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org}; 639b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 640b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 641b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine, 642b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel, 643b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : encoder_factory_(encoder_factory) { 645b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Connect the video and audio with |voice_channel|. 646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call::Config config(this); 647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(webrtc::Call::Create(config), engine); 648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 650b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 651b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine, 653b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 654b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : encoder_factory_(encoder_factory) { 655b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(call, engine); 656b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 657b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::Construct(webrtc::Call* call, 659b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine) { 660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_.reset(call); 663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_renderer_ = NULL; 664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_recv_ssrc_ = 0; 6666f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 6676f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org SetDefaultOptions(); 6686f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 6696f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 6706f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 6716f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org options_.video_noise_reduction.Set(true); 672543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org options_.use_payload_padding.Set(false); 6735ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options_.suspend_below_min_bitrate.Set(false); 674b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 675b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 679b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 684d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 685b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.begin(); 686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != receive_streams_.end(); 687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 688b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::Init() { return true; } 693b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace { 695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { 697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::stringstream out; 698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << '{'; 699b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << codecs[i].ToString(); 701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (i != codecs.size() - 1) { 702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << ", "; 703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 704b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << '}'; 706b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return out.str(); 707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 709e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.orgstatic bool ValidateCodecFormats(const std::vector<VideoCodec>& codecs) { 710e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org bool has_video = false; 711e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 712e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!codecs[i].ValidateCodecFormat()) { 713e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return false; 714e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 715e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (codecs[i].GetCodecType() == VideoCodec::CODEC_VIDEO) { 716e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org has_video = true; 717e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 718e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 719e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!has_video) { 720e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "Setting codecs without a video codec is invalid: " 721e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org << CodecVectorToString(codecs); 722e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return false; 723e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 724e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return true; 725e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org} 726e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 727587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.orgstatic std::string RtpExtensionsToString( 728587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 729587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org std::stringstream out; 730587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << '{'; 731587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 732587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; 733587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org if (i != extensions.size() - 1) { 734587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << ", "; 735587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org } 736587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org } 737587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << '}'; 738587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org return out.str(); 739587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org} 740587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org 741b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace 742b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 743b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 744b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 745b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 746b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 747b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 748b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 749b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 750b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 751b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without video codec payloads."; 752b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 753b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 754b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 755b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Add a decoder factory which controls supported codecs. 756b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Blocked on webrtc:2854. 757b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 758df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org if (_stricmp(mapped_codecs[i].codec.name.c_str(), kVp8CodecName) != 0) { 759b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported codec: '" 760b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << mapped_codecs[i].codec.name << "'"; 761b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 762b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 763b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 764b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 765b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org recv_codecs_ = mapped_codecs; 766d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 767d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 768d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 769d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 770d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 771d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 772d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 773d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 775b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 776b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 777b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 778b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 779b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 780b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 781b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 782b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 783b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 784b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 785b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 786b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 787b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No video codecs supported by encoder factory."; 788b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 789b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 790b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 791b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_codec_.Set(supported_codecs.front()); 792b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 793b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 794d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 795d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 796d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 797d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 798d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org assert(it->second != NULL); 799d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetCodec(supported_codecs.front()); 800d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 801b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 802b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 805b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 806b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodecSettings codec_settings; 807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 811b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *codec = codec_settings.codec; 812b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 813b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 814b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 815b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, 816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 823b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRender(bool render) { 826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. 827b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); 828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 829b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 830b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 831b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 832b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 833b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send && !send_codec_.IsSet()) { 834b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 835b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 836b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 837b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 838b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 839b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 840b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 841b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sp.ssrcs.empty()) { 849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No SSRCs in stream parameters."; 850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 851b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 853b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 855b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Make sure none of sp.ssrcs are used, not just the identifying 856b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ssrc. 857b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) != send_streams_.end()) { 858b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Send stream with ssrc '" << ssrc << "' already exists."; 859b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 860b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 861b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 8625301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> primary_ssrcs; 8635301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(&primary_ssrcs); 8645301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> rtx_ssrcs; 8655301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(primary_ssrcs, &rtx_ssrcs); 8665301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 8675301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_ERROR) 8685301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 8695301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << sp.ToString(); 870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 871b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 873b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoSendStream* stream = 8746ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org new WebRtcVideoSendStream(call_.get(), 8755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org encoder_factory_, 8766ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options_, 8775301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_codec_, 8785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp, 8795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_rtp_extensions_); 8805301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 885b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 896b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { 897b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 898b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 905b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 907b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 908b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 909b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<uint32, WebRtcVideoSendStream*>::iterator it = 910b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.find(ssrc); 911b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (it == send_streams_.end()) { 912b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 913b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 914b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 915b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 916b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.erase(it); 917b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 918b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 919b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 920b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 921b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 922b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 923b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 924b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 925b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 926b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); 927b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(sp.ssrcs.size() > 0); 928b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 929b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 930b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); // TODO(pbos): Is this ever valid? 931b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_recv_ssrc_ == 0) { 932b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_recv_ssrc_ = ssrc; 933b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 934b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 935b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Check if any of the SSRCs overlap. 936b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (receive_streams_.find(ssrc) != receive_streams_.end()) { 937b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Receive stream for SSRC " << ssrc << "already exists."; 938b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 939b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 940b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 941bd249bc711b3c9efd142eb8de3df489282fe693epbos@webrtc.org webrtc::VideoReceiveStream::Config config; 942d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ConfigureReceiverRtp(&config, sp); 943d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_[ssrc] = 944d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org new WebRtcVideoReceiveStream(call_.get(), config, recv_codecs_); 945d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 946d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 947d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 948d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 949d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 950d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 951d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const StreamParams& sp) const { 952d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 953d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 954d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remote_ssrc = ssrc; 955d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 956b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 957d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 958257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 959b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 960b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 961b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 962b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 963d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 964d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 965d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 966b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 967d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 968b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 969b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 970b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 971d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 972d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (recv_codecs_[i].codec.id == kDefaultVideoCodecPref.payload_type) { 973d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.fec = recv_codecs_[i].fec; 974d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 rtx_ssrc; 975d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 976d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 977d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].ssrc = rtx_ssrc; 978d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].payload_type = 979d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org recv_codecs_[i].rtx_payload_type; 980b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 981d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org break; 982b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 983b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 984b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 985b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 986b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 987b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { 988b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 989b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 990b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_recv_ssrc_; 991b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 992b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 993d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator stream = 994b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 995b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 996b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 997b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 998b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 999d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org delete stream->second; 1000b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 1001b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1002b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_recv_ssrc_) { 1003b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_recv_ssrc_ = 0; 1004b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1005b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1006b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1007b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1008b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1009b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 1010b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 1011b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 1012b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1013d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (default_recv_ssrc_!= 0) { 1014d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_[default_recv_ssrc_]->SetRenderer(renderer); 1015d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1016b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_recv_ssrc_; 1017b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_renderer_ = renderer; 1018d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1019b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1020b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1021d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1022d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1023d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1024d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return false; 1025b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1026b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1027b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1028b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1029b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1030b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1031b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { 1032b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1033b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_renderer_ == NULL) { 1034b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1035b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1036b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = default_renderer_; 1037b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1038b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1039b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1040d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1041d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1042d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1043b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1044b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1045b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1046b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1047b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1048b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1049b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(const StatsOptions& options, 1050b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoMediaInfo* info) { 1051e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info->Clear(); 1052e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillSenderStats(info); 1053e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillReceiverStats(info); 1054e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillBandwidthEstimationStats(info); 1055b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1056b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1057b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1058e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 1059e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1060e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org send_streams_.begin(); 1061e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != send_streams_.end(); 1062e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1063e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 1064e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1065e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1066e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1067e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 1068e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1069e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org receive_streams_.begin(); 1070e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != receive_streams_.end(); 1071e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1072e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 1073e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1074e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1075e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1076e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 1077e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoMediaInfo* video_media_info) { 1078e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Implement. 1079e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1080e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1081b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 1082b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1083b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 1084b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1085b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1086b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1087b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1088b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1089b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetCapturer(capturer); 1090b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1091b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1092b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1093b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1094b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1095b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1096b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1097b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1098b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1099b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1100b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1101b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1102b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1103b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1105d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1106d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11074e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 11084e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org call_->Receiver()->DeliverPacket( 11094e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()); 11104e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 11114e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 11124e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11134e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 11144e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11154e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 11164e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = 0; 1120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 11214e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 1122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!GetRtpSsrc(packet->data(), packet->length(), &ssrc)) { 1126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StreamParams sp; 1130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sp.ssrcs.push_back(ssrc); 1131c34bb3a88627672d99b1c037d36dbeb23407fae4pbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 1132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org AddRecvStream(sp); 1133d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRenderer(0, default_renderer_); 1134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 11351e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 11361e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 11371e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 11381e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet after creating default " 11391e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org "receiver."; 1140b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1141b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1142b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1143b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1144b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1145d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1146d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11471e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 11481e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 11491e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1150b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTCP packet."; 1151b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1152b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1153b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1154b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 1155b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "OnReadySend: " << (ready ? "Ready." : "Not ready."); 1156b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1157b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1158b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { 1159b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1160b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 1161b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1162b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->MuteStream(mute); 1167b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1168b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1169b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1170b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1171587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " 1172587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 11733c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 11743c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1175d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 11763c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org recv_rtp_extensions_ = FilterRtpExtensions(extensions); 1177d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1178d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 1179d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 1180d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1181d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 1182d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1183b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1184b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1188587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " 1189587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 11903c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 11913c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 11923c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 11933c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org send_rtp_extensions_ = FilterRtpExtensions(extensions); 1194d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1195d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 1196d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 1197d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1198d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 1199d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1200b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1201b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1202b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1203b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetStartSendBandwidth(int bps) { 1204b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1205b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetStartSendBandwidth: " << bps; 1206b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1207b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1208b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1209b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int bps) { 1210b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1211b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetMaxSendBandwidth: " << bps; 1212b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1213b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1214b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1215b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 1216b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); 1217b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 12185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 12195301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_streams_.begin(); 12205301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it != send_streams_.end(); 12215301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ++it) { 12225301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it->second->SetOptions(options_); 12235301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1224b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1225b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1226b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1227b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1228b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1229b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1230b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1231d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Socket::OPT_RCVBUF, 1232b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1233b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1234b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(sriniv): Remove or re-enable this. 1235b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // As part of b/8030474, send-buffer is size now controlled through 1236b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // portallocator flags. 1237b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // network_interface_->SetOption(NetworkInterface::ST_RTP, 1238d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org // rtc::Socket::OPT_SNDBUF, 1239b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // kVideoRtpBufferSize); 1240b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1241b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1242b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1243b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1244b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1245b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1246d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(rtc::Message* msg) { 1247b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1248b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1249b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1250b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { 1251d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendPacket(&packet); 1253b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1254b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1255b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1256d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1257b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendRtcp(&packet); 1258b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1259b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1260b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1261b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1262b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1263b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1264b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1265b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1266b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1267b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1268b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1269b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1270b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1271b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1272b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1273b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1274b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1275b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1276b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1277b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 12786ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 12796ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 12806ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 12816ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 12825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings) 12835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org : config(config), options(options), codec_settings(codec_settings) { 12846ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org} 12856ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 1286b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1287b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 12885301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory, 12896ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 12905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings, 12915301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const StreamParams& sp, 12925301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) 1293b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : call_(call), 12945301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_(webrtc::VideoSendStream::Config(), options, codec_settings), 1295b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org encoder_factory_(encoder_factory), 1296b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_(NULL), 1297b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 1298b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 12995301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org muted_(false) { 13005301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 13015301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13025301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 13035301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 13045301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 13055301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 13065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 13075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13085301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings params; 13095301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (codec_settings.Get(¶ms)) { 13105301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodec(params); 13115301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1312b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 13165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 13175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org call_->DestroyVideoSendStream(stream_); 13185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 13196ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org delete parameters_.config.encoder_settings.encoder; 1320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void SetWebRtcFrameToBlack(webrtc::I420VideoFrame* video_frame) { 1323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(video_frame != NULL); 1324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 1325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 16, 1326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 1328b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 1331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1332b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1333b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1334b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1335b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void CreateBlackFrame(webrtc::I420VideoFrame* video_frame, 1336b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->CreateEmptyFrame( 1339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org width, height, width, (width + 1) / 2, (width + 1) / 2); 1340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetWebRtcFrameToBlack(video_frame); 1341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1342b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1343b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void ConvertToI420VideoFrame(const VideoFrame& frame, 1344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::I420VideoFrame* i420_frame) { 1345b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org i420_frame->CreateFrame( 1346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch() * frame.GetHeight()), 1347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetYPlane(), 1348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch() * ((frame.GetHeight() + 1) / 2)), 1349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetUPlane(), 1350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch() * ((frame.GetHeight() + 1) / 2)), 1351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetVPlane(), 1352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetWidth()), 1353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetHeight()), 1354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch()), 1355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch()), 1356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch())); 1357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 1362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "InputFrame: " << frame->GetWidth() << "x" 1363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << frame->GetHeight(); 1364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org bool is_screencast = capturer->IsScreencast(); 1365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock before copying, can be called concurrently when swapping input source. 1366d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope frame_cs(&frame_lock_); 1367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!muted_) { 1368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ConvertToI420VideoFrame(*frame, &video_frame_); 1369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Create a tiny black frame to transmit instead. 1371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org CreateBlackFrame(&video_frame_, 1, 1); 1372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org is_screencast = false; 1373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1374d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 13755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ == NULL) { 13765301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_WARNING) << "Capturer inputting frames before send codecs are " 13775301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org "configured, dropping."; 13785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org return; 13795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 1381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(format_.height == 0); 1382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (is_screencast) { 1387b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetDimensions(video_frame_.width(), video_frame_.height()); 1388b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1389b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SwapFrame: " << video_frame_.width() << "x" 1390b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << video_frame_.height() << " -> (codec) " 13916ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.video_streams.back().width << "x" 13926ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.video_streams.back().height; 1393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Input()->SwapFrame(&video_frame_); 1394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1395b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1398b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1399b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1400b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1403d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1404b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14059359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (capturer == NULL) { 14069359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (stream_ != NULL) { 14079359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 14089359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org webrtc::I420VideoFrame black_frame; 14099359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org 14109359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int width = format_.width; 14119359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int height = format_.height; 14129359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int half_width = (width + 1) / 2; 14139359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org black_frame.CreateEmptyFrame( 14149359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org width, height, width, half_width, half_width); 14159359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org SetWebRtcFrameToBlack(&black_frame); 14169359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org SetDimensions(width, height); 14179359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org stream_->Input()->SwapFrame(&black_frame); 14189359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org } 1419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1423b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1424b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1431b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1441d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1444b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 14456ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1446b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 14486ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().max_framerate = 1449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetDimensions(format.width, format.height); 1451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1458d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org bool was_muted = muted_; 1460b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1461b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return was_muted != mute; 1462b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1465d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1466b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (capturer_ == NULL) { 1467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_->SignalVideoFrame.disconnect(this); 1470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1471b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14745301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 14755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1476d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 14775301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings codec_settings; 14785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (parameters_.codec_settings.Get(&codec_settings)) { 14795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, options); 14805301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } else { 14815301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.options = options; 14825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 14835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 1484b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 14855301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings) { 1486d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 14875301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 14885301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 14895301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 14905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings, 14915301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 14926ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org std::vector<webrtc::VideoStream> video_streams = 14936ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org encoder_factory_->CreateVideoStreams( 14945301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec, options, parameters_.config.rtp.ssrcs.size()); 14956ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (video_streams.empty()) { 1496b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 14986ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams = video_streams; 14995301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 15005301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec.height, 1501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 1502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 15036ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15046ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org webrtc::VideoEncoder* old_encoder = 15056ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config.encoder_settings.encoder; 15066ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config.encoder_settings.encoder = 15075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org encoder_factory_->CreateVideoEncoder(codec_settings.codec, options); 15085301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 15095301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 15105301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 15115301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15125301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org // Set RTX payload type if RTX is enabled. 15135301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 15145301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 1515543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1516543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org options.use_payload_padding.Get( 1517543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org ¶meters_.config.rtp.rtx.pad_with_redundant_payloads); 15185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15195301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15205301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (IsNackEnabled(codec_settings.codec)) { 15215301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.nack.rtp_history_ms = kNackHistoryMs; 15225301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15235301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15245ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options.suspend_below_min_bitrate.Get( 15255ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org ¶meters_.config.suspend_below_min_bitrate); 15265ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org 15275301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.codec_settings.Set(codec_settings); 15286ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 1529543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1530b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 1531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete old_encoder; 1532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1534d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 1535d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 1536d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1537d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 1538d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1539d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1540d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1541b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions(int width, 15426ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org int height) { 15436ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org assert(!parameters_.video_streams.empty()); 1544b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height; 15456ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (parameters_.video_streams.back().width == width && 15466ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().height == height) { 1547b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 15516ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().width = width; 15526ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().height = height; 15536ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15546f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 15556f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 15566f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org void* encoder_settings = encoder_factory_->CreateVideoEncoderSettings( 15576f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org codec_settings.codec, parameters_.options); 15586f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 15596f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder( 15606f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.video_streams, encoder_settings); 15616f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 15626f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings(codec_settings.codec, 15636f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_settings); 15646f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 15656f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (!stream_reconfigured) { 1566b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 1567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 1568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 1573d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 15745301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org assert(stream_ != NULL); 1575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 1577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 1580d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 15815301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 15825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org stream_->Stop(); 15835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1584b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 1585b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1586b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1587e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoSenderInfo 1588e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 1589e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoSenderInfo info; 1590d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1591e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (size_t i = 0; i < parameters_.config.rtp.ssrcs.size(); ++i) { 1592e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(parameters_.config.rtp.ssrcs[i]); 1593e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1594e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1595c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org if (stream_ == NULL) { 1596c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org return info; 1597c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org } 1598c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org 1599e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 1600e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_input = stats.input_frame_rate; 1601e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 1602e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1603e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32_t, webrtc::StreamStats>::iterator it = 1604e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.substreams.begin(); 1605e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != stats.substreams.end(); 1606e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1607e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 1608e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::StreamStats stream_stats = it->second; 1609e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.bytes_sent += stream_stats.rtp_stats.bytes + 1610e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stream_stats.rtp_stats.header_bytes + 1611e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stream_stats.rtp_stats.padding_bytes; 1612e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_sent += stream_stats.rtp_stats.packets; 1613e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 1614e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1615e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1616e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (!stats.substreams.empty()) { 1617e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 1618e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::StreamStats first_stream_stats = stats.substreams.begin()->second; 1619e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.fraction_lost = 1620e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 1621e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org (1 << 8); 1622e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1623e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1624e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (capturer_ != NULL && !capturer_->IsMuted()) { 1625e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoFormat last_captured_frame_format; 1626e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, 1627e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &info.effects_frame_drops, 1628e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &info.capturer_frame_time, 1629e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &last_captured_frame_format); 1630e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 1631e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 1632e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.send_frame_width = 1633e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<int>(parameters_.video_streams.front().width); 1634e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.send_frame_height = 1635e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<int>(parameters_.video_streams.front().height); 1636e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1637e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1638e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Support or remove the following stats. 1639e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_cached = -1; 1640e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.rtt_ms = -1; 1641e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1642e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 1643e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1644e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1645b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 1646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 1647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 1648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 16496ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 16506f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 16516f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 16526f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org void* encoder_settings = encoder_factory_->CreateVideoEncoderSettings( 16536f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org codec_settings.codec, parameters_.options); 16546f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 16556ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org stream_ = call_->CreateVideoSendStream( 16566f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.config, parameters_.video_streams, encoder_settings); 16576f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 16586f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings(codec_settings.codec, 16596f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_settings); 16606f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 1662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1666d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 1667d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::Call* call, 1668d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::VideoReceiveStream::Config& config, 1669d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) 1670d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org : call_(call), 1671d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_(config), 1672d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_(NULL), 1673d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_(-1), 1674d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_(-1), 1675d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_(NULL) { 1676d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.renderer = this; 1677d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 1678d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRecvCodecs(recv_codecs); 1679d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1680d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1681d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 1682d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1683d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1684d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1685d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 1686d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 1687d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 1688d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Base receive codecs off recv_codecs_ and set up using a 1689d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // DecoderFactory similar to send side. Pending webrtc:2854. 1690d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // Also set up default codecs if there's nothing in recv_codecs_. 1691d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoCodec codec; 1692d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org memset(&codec, 0, sizeof(codec)); 1693d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1694d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.plType = kDefaultVideoCodecPref.payload_type; 1695d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org strcpy(codec.plName, kDefaultVideoCodecPref.name); 1696d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecType = webrtc::kVideoCodecVP8; 1697d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.resilience = webrtc::kResilientStream; 1698d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.numberOfTemporalLayers = 1; 1699d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.denoisingOn = true; 1700d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.errorConcealmentOn = false; 1701d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.automaticResizeOn = false; 1702d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.frameDroppingOn = true; 1703d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.keyFrameInterval = 3000; 1704d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // Bitrates don't matter and are ignored for the receiver. This is put in to 1705d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // have the current underlying implementation accept the VideoCodec. 1706d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.minBitrate = codec.startBitrate = codec.maxBitrate = 300; 1707d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.codecs.clear(); 1708d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.codecs.push_back(codec); 1709d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1710d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 1711d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1712257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.nack.rtp_history_ms = 1713257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org IsNackEnabled(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 1714257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.remb = IsRembEnabled(recv_codecs.begin()->codec); 1715257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 1716d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1717d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1718d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1719d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 1720d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 1721d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.extensions = extensions; 1722d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1723d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1724d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1725d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 1726d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (stream_ != NULL) { 1727d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1728d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1729d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 1730d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_->Start(); 1731d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1732d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1733d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 1734d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::I420VideoFrame& frame, 1735d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int time_to_render_ms) { 1736d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1737d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ == NULL) { 1738d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 1739d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return; 1740d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1741d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1742d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 1743d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(frame.width(), frame.height()); 1744d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1745d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1746d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_VERBOSE) << "RenderFrame: (" << frame.width() << "x" << frame.height() 1747d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org << ")"; 1748d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1749d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const WebRtcVideoRenderFrame render_frame(&frame); 1750d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_->RenderFrame(&render_frame); 1751d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1752d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1753d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 1754d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org cricket::VideoRenderer* renderer) { 1755d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1756d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_ = renderer; 1757d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 1758d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(last_width_, last_height_); 1759d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1760d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1761d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1762d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 1763d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 1764d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // design. 1765d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1766d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return renderer_; 1767d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1768d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1769d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 1770d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int height) { 1771d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1772d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 1773d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 1774d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1775d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_ = width; 1776d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_ = height; 1777d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1778d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1779e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoReceiverInfo 1780e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 1781e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoReceiverInfo info; 1782e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 1783e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 1784e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.bytes_rcvd = stats.rtp_stats.bytes + stats.rtp_stats.header_bytes + 1785e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.rtp_stats.padding_bytes; 1786e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_rcvd = stats.rtp_stats.packets; 1787e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1788e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 1789e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 1790e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_output = stats.render_frame_rate; 1791e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1792d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope frame_cs(&renderer_lock_); 1793e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.frame_width = last_width_; 1794e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.frame_height = last_height_; 1795e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1796e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Support or remove the following stats. 1797e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_concealed = -1; 1798e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1799e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 1800e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1801e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1802b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 1803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 1804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1805b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 1806b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 1807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!codecs.empty()); 1808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 1810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 1811e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 1812b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, int> rtx_mapping; // video payload type -> rtx payload type. 1813b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1814b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 1815b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 1817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 1818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 1819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 1821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 1822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 1823b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 1826e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 1827b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 1829b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 1830b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 1831b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.red_payload_type == -1); 1832b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 1833b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1834b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1835b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1836b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 1837b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 1838b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.ulpfec_payload_type == -1); 1839b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 1840b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1841b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 1844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 1845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 1846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org &associated_payload_type)) { 1847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RTX codec without associated payload type: " 1848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 1849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1851b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 1852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1853b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1855b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 1856b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 1857b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1858b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1859b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 1860b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 1861b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1862b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1863b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 1864b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 1865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!video_codecs.empty()); 1866b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1867e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 1868e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org it != rtx_mapping.end(); 1869e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org ++it) { 1870e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!payload_used[it->first]) { 1871e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 1872e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1873e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1874e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO) { 1875e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX not mapped to regular video codec."; 1876e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1877e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1878e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1879e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 1880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Write tests that figure out that I have not verified that RTX 1881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // codecs aren't mapped to bogus payloads. 1882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 1883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 1884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtx_mapping[video_codecs[i].codec.id] != 0) { 1885b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 1886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 1890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 1893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 1894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) { 1895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 1896b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 1897b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (encoder_factory_->SupportsCodec(mapped_codecs[i].codec)) { 1898b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org supported_codecs.push_back(mapped_codecs[i]); 1899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return supported_codecs; 1902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 1905b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 1907