webrtcvideoengine2.cc revision b648b9d85c5d07b0866ef45f5be587f71b0849b4
1b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org/* 2b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * libjingle 3b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Copyright 2014 Google Inc. 4b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 5b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * Redistribution and use in source and binary forms, with or without 6b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * modification, are permitted provided that the following conditions are met: 7b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 8b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 9b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * this list of conditions and the following disclaimer. 10b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 11b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * this list of conditions and the following disclaimer in the documentation 12b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * and/or other materials provided with the distribution. 13b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 3. The name of the author may not be used to endorse or promote products 14b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * derived from this software without specific prior written permission. 15b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * 16b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org */ 27b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 28b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#ifdef HAVE_WEBRTC_VIDEO 29b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoengine2.h" 30b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 313c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org#include <set> 32b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include <string> 33b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 34b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "libyuv/convert_from.h" 35b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videocapturer.h" 36b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videorenderer.h" 37df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org#include "talk/media/webrtc/constants.h" 38b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideocapturer.h" 39b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoframe.h" 40b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvoiceengine.h" 41a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/buffer.h" 42a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/logging.h" 43a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "webrtc/base/stringutils.h" 44b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/call.h" 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; 6297fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org int width; 6397fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org int height; 64b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const char* name; 65b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rtx_payload_type; 6697fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org} kDefaultVideoCodecPref = {100, 640, 400, kVp8CodecName, 96}; 67b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 6897fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.orgVideoCodecPref kRedPref = {116, -1, -1, kRedCodecName, -1}; 6997fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.orgVideoCodecPref kUlpfecPref = {117, -1, -1, kUlpfecCodecName, -1}; 70b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 71b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 72b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& requested_codec, 73b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* matching_codec) { 74b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 75b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 76b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *matching_codec = codecs[i]; 77b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 78b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 79b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 80b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 81b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 82b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 83f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.orgstatic void AddDefaultFeedbackParams(VideoCodec* codec) { 84f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kFir(kRtcpFbParamCcm, kRtcpFbCcmParamFir); 85f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kFir); 86f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kNack(kRtcpFbParamNack, kParamValueEmpty); 87f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kNack); 88f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kPli(kRtcpFbParamNack, kRtcpFbNackParamPli); 89f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kPli); 90f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kRemb(kRtcpFbParamRemb, kParamValueEmpty); 91f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kRemb); 92f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org} 93f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org 94f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.orgstatic bool IsNackEnabled(const VideoCodec& codec) { 95f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org return codec.HasFeedbackParam( 96f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); 97f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org} 98f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org 99257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.orgstatic bool IsRembEnabled(const VideoCodec& codec) { 100257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org return codec.HasFeedbackParam( 101257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); 102257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org} 103257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultVideoCodec() { 105b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec default_codec(kDefaultVideoCodecPref.payload_type, 106b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.name, 10797fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org kDefaultVideoCodecPref.width, 10897fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org kDefaultVideoCodecPref.height, 109b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultFramerate, 110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 0); 111f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org AddDefaultFeedbackParams(&default_codec); 112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return default_codec; 113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultRedCodec() { 116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kRedPref.payload_type, kRedPref.name, 0, 0, 0, 0); 117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultUlpfecCodec() { 120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kUlpfecPref.payload_type, kUlpfecPref.name, 0, 0, 0, 0); 121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic std::vector<VideoCodec> DefaultVideoCodecs() { 124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodec> codecs; 125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultVideoCodec()); 126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultRedCodec()); 127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultUlpfecCodec()); 128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (kDefaultVideoCodecPref.rtx_payload_type != -1) { 129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back( 130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec::CreateRtxCodec(kDefaultVideoCodecPref.rtx_payload_type, 131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.payload_type)); 132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return codecs; 134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1363c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic bool ValidateRtpHeaderExtensionIds( 1373c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1383c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::set<int> extensions_used; 1393c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1403c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (extensions[i].id < 0 || extensions[i].id >= 15 || 1413c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org !extensions_used.insert(extensions[i].id).second) { 1423c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; 1433c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1443c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1453c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1463c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return true; 1473c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 1483c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1493c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic std::vector<webrtc::RtpExtension> FilterRtpExtensions( 1503c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1513c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::vector<webrtc::RtpExtension> webrtc_extensions; 1523c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1533c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org // Unsupported extensions will be ignored. 1543c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (webrtc::RtpExtension::IsSupported(extensions[i].uri)) { 1553c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org webrtc_extensions.push_back(webrtc::RtpExtension( 1563c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org extensions[i].uri, extensions[i].id)); 1573c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } else { 1583c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; 1593c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1603c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1613c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return webrtc_extensions; 1623c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 1633c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1640d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.orgWebRtcVideoEncoderFactory2::~WebRtcVideoEncoderFactory2() { 1650d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org} 1660d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org 167d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgstd::vector<webrtc::VideoStream> WebRtcVideoEncoderFactory2::CreateVideoStreams( 168d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 169d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 170d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 171d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org assert(SupportsCodec(codec)); 172d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org if (num_streams != 1) { 173d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org LOG(LS_ERROR) << "Unsupported number of streams: " << num_streams; 174d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return std::vector<webrtc::VideoStream>(); 1756ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org } 176b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 177d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 178d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 179d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 180d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 181d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultFramerate; 182d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 183d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int min_bitrate = kMinVideoBitrate; 184d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMinBitrate, &min_bitrate); 185d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int max_bitrate = kMaxVideoBitrate; 186d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxBitrate, &max_bitrate); 187d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.min_bitrate_bps = min_bitrate * 1000; 188d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate * 1000; 189d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 190d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int max_qp = 56; 191d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 192d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 193d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 194d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 195d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 196d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 197b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 198d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgwebrtc::VideoEncoder* WebRtcVideoEncoderFactory2::CreateVideoEncoder( 199d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 200d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options) { 201d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org assert(SupportsCodec(codec)); 2026f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2036f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return webrtc::VP8Encoder::Create(); 2046f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2056f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org // This shouldn't happen, we should be able to create encoders for all codecs 2066f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org // we support. 2076f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(false); 2086f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 2096f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 2106f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2116f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid* WebRtcVideoEncoderFactory2::CreateVideoEncoderSettings( 2126f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 2136f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoOptions& options) { 2146f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(SupportsCodec(codec)); 2156f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2166f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org webrtc::VideoCodecVP8* settings = new webrtc::VideoCodecVP8(); 2176f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->resilience = webrtc::kResilientStream; 2186f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->numberOfTemporalLayers = 1; 2196f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org options.video_noise_reduction.Get(&settings->denoisingOn); 2206f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->errorConcealmentOn = false; 2216f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->automaticResizeOn = false; 2226f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->frameDroppingOn = true; 2236f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->keyFrameInterval = 3000; 2246f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return settings; 2256f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2266f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 2276f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 2286f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2296f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoEncoderFactory2::DestroyVideoEncoderSettings( 2306f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 2316f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org void* encoder_settings) { 2326f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(SupportsCodec(codec)); 2336f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (encoder_settings == NULL) { 2346f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return; 2356f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2366f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2376f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2386f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org delete reinterpret_cast<webrtc::VideoCodecVP8*>(encoder_settings); 2396f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return; 2406f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2416f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org // We should be able to destroy all encoder settings we've allocated. 2426f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(false); 243d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 244d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 245d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgbool WebRtcVideoEncoderFactory2::SupportsCodec(const VideoCodec& codec) { 246df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org return _stricmp(codec.name.c_str(), kVp8CodecName) == 0; 247d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 248b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 249afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgDefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler() 250afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org : default_recv_ssrc_(0), default_renderer_(NULL) {} 251afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 252afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgUnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc( 253afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 254afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org uint32_t ssrc) { 255afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 256afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 257afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDropPacket; 258afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 259afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 260afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org StreamParams sp; 261afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org sp.ssrcs.push_back(ssrc); 262afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 263afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (!channel->AddRecvStream(sp)) { 264afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Could not create default receive stream."; 265afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 266afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 267afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(ssrc, default_renderer_); 268afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_recv_ssrc_ = ssrc; 269afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDeliverPacket; 270afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 271afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 272afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgVideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { 273afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return default_renderer_; 274afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 275afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 276afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgvoid DefaultUnsignalledSsrcHandler::SetDefaultRenderer( 277afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 278afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoRenderer* renderer) { 279afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_renderer_ = renderer; 280afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { 281afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(default_recv_ssrc_, default_renderer_); 282afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 283afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 284afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 28597fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2() 286b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : worker_thread_(NULL), 287b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org voice_engine_(NULL), 288b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org video_codecs_(DefaultVideoCodecs()), 289b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org default_codec_format_(kDefaultVideoCodecPref.width, 29097fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org kDefaultVideoCodecPref.height, 29197fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org FPS_TO_INTERVAL(kDefaultFramerate), 292b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org FOURCC_ANY), 293b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org initialized_(false), 294b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org cpu_monitor_(new rtc::CpuMonitor(NULL)), 295b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org channel_factory_(NULL) { 296b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; 297587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 298587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 299587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpTimestampOffsetHeaderExtensionDefaultId)); 300587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 301587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 302587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 303b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 304b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 305b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.orgvoid WebRtcVideoEngine2::SetChannelFactory( 306b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org WebRtcVideoChannelFactory* channel_factory) { 307b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org channel_factory_ = channel_factory; 308b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org} 309b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org 310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 311b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 312b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Terminate(); 315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 316b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 317b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 318d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgbool WebRtcVideoEngine2::Init(rtc::Thread* worker_thread) { 319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org worker_thread_ = worker_thread; 321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(worker_thread_ != NULL); 322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->set_thread(worker_thread_); 324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!cpu_monitor_->Start(kCpuMonitorPeriodMs)) { 325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Failed to start CPU monitor."; 326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_.reset(); 327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 328b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 332b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 333b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::Terminate() { 334b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Terminate"; 335b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 336b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->Stop(); 337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = false; 339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgint WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } 342b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 343b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetOptions(const VideoOptions& options) { 344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Do we need this? This is a no-op in the existing 345b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // WebRtcVideoEngine implementation. 346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); 347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // options_ = options; 348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoEncoderConfig& config) { 3538fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org const VideoCodec& codec = config.max_codec; 3548fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org // TODO(pbos): Make use of external encoder factory. 3558fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (!GetVideoEncoderFactory()->SupportsCodec(codec)) { 3568fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported:" 3578fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org << codec.ToString(); 3588fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return false; 3598fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 3608fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 3618fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org default_codec_format_ = 3628fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoFormat(codec.width, 3638fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org codec.height, 3648fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoFormat::FpsToInterval(codec.framerate), 3658fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org FOURCC_ANY); 3668fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org video_codecs_.clear(); 3678fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org video_codecs_.push_back(codec); 368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoEncoderConfig WebRtcVideoEngine2::GetDefaultEncoderConfig() const { 372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoEncoderConfig(DefaultVideoCodec()); 373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 374b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 375b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel) { 377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "CreateChannel: " 378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (voice_channel != NULL ? "With" : "Without") 379b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << " voice channel."; 380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoChannel2* channel = 381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org channel_factory_ != NULL 382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ? channel_factory_->Create(this, voice_channel) 383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : new WebRtcVideoChannel2( 3840d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org this, voice_channel, GetVideoEncoderFactory()); 385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!channel->Init()) { 386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete channel; 387b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 388b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 389e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org channel->SetRecvCodecs(video_codecs_); 390b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return channel; 391b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 392b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 395b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 398b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 399b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return rtp_header_extensions_; 400b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { 403b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Set up logging. 404b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; 405b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if min_sev == -1, we keep the current log level. 406b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (min_sev < 0) { 407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(min_sev == -1); 408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 409b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 415b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 416b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 417b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 418b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 4228fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 4238fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 4248fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (codec.Matches(in)) { 4258fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 431b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// dimensions will be used for aspect ratio matching. 435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& current, 437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* out) { 438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(out != NULL); 439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width != requested.height && 441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // 0xn and nx0 are invalid resolutions. 443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 444b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 445b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 446b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec matching_codec; 447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Codec not supported. 449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->id = requested.id; 453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->name = requested.name; 454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->preference = requested.preference; 455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->framerate = 457d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::_min(requested.framerate, matching_codec.framerate); 458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->feedback_params = requested.feedback_params; 4608fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width = requested.width; 4618fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height = requested.height; 4628fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 4638fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 4648fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 4658fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 4668fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org while (out->width > matching_codec.width) { 4678fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width /= 2; 4688fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height /= 2; 4698fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 4708fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 4718fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return out->width > 0 && out->height > 0; 472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetVoiceEngine(WebRtcVoiceEngine* voice_engine) { 475b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 476b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "SetVoiceEngine can not be called after Init"; 477b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 478b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 479b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org voice_engine_ = voice_engine; 480b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 481b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 483b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 484b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 485b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 486b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 490b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 491b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 495d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgWebRtcVideoEncoderFactory2* WebRtcVideoEngine2::GetVideoEncoderFactory() { 496d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return &default_video_encoder_factory_; 497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 4996ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org// Thin map between VideoFrame and an existing webrtc::I420VideoFrame 500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// to avoid having to copy the rendered VideoFrame prematurely. 501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This implementation is only safe to use in a const context and should never 502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be written to. 5036ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgclass WebRtcVideoRenderFrame : public VideoFrame { 504b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org public: 505b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org explicit WebRtcVideoRenderFrame(const webrtc::I420VideoFrame* frame) 506b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : frame_(frame) {} 507b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 508b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool InitToBlack(int w, 509b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 510b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 513b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) OVERRIDE { 514b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 515b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 516b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 517b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 518b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool Reset(uint32 fourcc, 519b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int w, 520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dw, 522b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dh, 523b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* sample, 524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t sample_size, 525b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp, 529b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rotation) OVERRIDE { 530b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetWidth() const OVERRIDE { 535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->width()); 536b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 537b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetHeight() const OVERRIDE { 538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->height()); 539b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 540b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 541b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetYPlane() const OVERRIDE { 542b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kYPlane); 543b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 544b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetUPlane() const OVERRIDE { 545b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kUPlane); 546b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 547b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetVPlane() const OVERRIDE { 548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kVPlane); 549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetYPlane() OVERRIDE { 552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 554b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetUPlane() OVERRIDE { 556b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 557b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetVPlane() OVERRIDE { 560b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 561b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 562b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 563b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 564b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetYPitch() const OVERRIDE { 565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kYPlane); 566b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetUPitch() const OVERRIDE { 568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kUPlane); 569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetVPitch() const OVERRIDE { 571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kVPlane); 572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void* GetNativeHandle() const OVERRIDE { return NULL; } 575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelWidth() const OVERRIDE { return 1; } 577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelHeight() const OVERRIDE { return 1; } 578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetElapsedTime() const OVERRIDE { 580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert millisecond render time to ns timestamp. 581d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org return frame_->render_time_ms() * rtc::kNumNanosecsPerMillisec; 582b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 583b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetTimeStamp() const OVERRIDE { 584b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert 90K rtp timestamp to ns timestamp. 585d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org return (frame_->timestamp() / 90) * rtc::kNumNanosecsPerMillisec; 586b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 587b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetElapsedTime(int64 elapsed_time) OVERRIDE { UNIMPLEMENTED; } 588b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetTimeStamp(int64 time_stamp) OVERRIDE { UNIMPLEMENTED; } 589b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 590b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int GetRotation() const OVERRIDE { 591b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 592b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return ROTATION_0; 593b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 594b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 595b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* Copy() const OVERRIDE { 596b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 599b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 600b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool MakeExclusive() OVERRIDE { 601b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 602b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 605b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t CopyToBuffer(uint8* buffer, size_t size) const { 606b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; 608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(fbarchard): Refactor into base class and share with LMI 611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, 612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* buffer, 613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t size, 614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int stride_rgb) const OVERRIDE { 615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t width = GetWidth(); 616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t height = GetHeight(); 617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t needed = (stride_rgb >= 0 ? stride_rgb : -stride_rgb) * height; 618b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (size < needed) { 619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "RGB buffer is not large enough"; 620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (libyuv::ConvertFromI420(GetYPlane(), 624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetYPitch(), 625b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPlane(), 626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPitch(), 627b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPlane(), 628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPitch(), 629b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org buffer, 630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stride_rgb, 631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(width), 632b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(height), 633b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org to_fourcc)) { 634b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RGB type not supported: " << to_fourcc; 635b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; // 0 indicates error 636b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 637b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 638b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 639b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 640b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org protected: 641b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* CreateEmptyFrame(int w, 642b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 643b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 645b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) const OVERRIDE { 647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoFrame* frame = new WebRtcVideoFrame(); 648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame->InitToBlack( 649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org w, h, pixel_width, pixel_height, elapsed_time, time_stamp); 650b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame; 651b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 653b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org private: 654b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const webrtc::I420VideoFrame* const frame_; 655b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org}; 656b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 657b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine, 659b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel, 660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 661b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 662b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org encoder_factory_(encoder_factory) { 663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Connect the video and audio with |voice_channel|. 664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call::Config config(this); 665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(webrtc::Call::Create(config), engine); 666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 667b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 668b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 669b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine, 671b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 672b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 673b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org encoder_factory_(encoder_factory) { 674b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(call, engine); 675b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::Construct(webrtc::Call* call, 678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine) { 679b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_.reset(call); 682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 6836f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 6846f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org SetDefaultOptions(); 6856f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 6866f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 6876f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 6886f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org options_.video_noise_reduction.Set(true); 689543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org options_.use_payload_padding.Set(false); 6905ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options_.suspend_below_min_bitrate.Set(false); 691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 693b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 699b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 701d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.begin(); 703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != receive_streams_.end(); 704b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 706b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 709b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::Init() { return true; } 710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 711b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace { 712b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 713b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { 714b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::stringstream out; 715b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << '{'; 716b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 717b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << codecs[i].ToString(); 718b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (i != codecs.size() - 1) { 719b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << ", "; 720b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 721b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 722b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << '}'; 723b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return out.str(); 724b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 725b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 726e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.orgstatic bool ValidateCodecFormats(const std::vector<VideoCodec>& codecs) { 727e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org bool has_video = false; 728e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 729e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!codecs[i].ValidateCodecFormat()) { 730e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return false; 731e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 732e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (codecs[i].GetCodecType() == VideoCodec::CODEC_VIDEO) { 733e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org has_video = true; 734e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 735e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 736e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!has_video) { 737e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "Setting codecs without a video codec is invalid: " 738e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org << CodecVectorToString(codecs); 739e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return false; 740e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 741e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return true; 742e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org} 743e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 744587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.orgstatic std::string RtpExtensionsToString( 745587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 746587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org std::stringstream out; 747587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << '{'; 748587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 749587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; 750587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org if (i != extensions.size() - 1) { 751587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << ", "; 752587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org } 753587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org } 754587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << '}'; 755587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org return out.str(); 756587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org} 757587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org 758b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace 759b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 760b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 761b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 762b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 763b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 764b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 765b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 766b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 767b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 768b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without video codec payloads."; 769b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 770b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 771b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 772b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Add a decoder factory which controls supported codecs. 773b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Blocked on webrtc:2854. 774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 775df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org if (_stricmp(mapped_codecs[i].codec.name.c_str(), kVp8CodecName) != 0) { 776b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported codec: '" 777b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << mapped_codecs[i].codec.name << "'"; 778b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 779b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 780b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 781b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 782b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org recv_codecs_ = mapped_codecs; 783d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 784d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 785d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 786d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 787d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 788d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 789d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 790d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 791b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 792b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 793b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 794b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 795b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 796b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 797b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 798b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 799b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 800b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 801b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 802b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No video codecs supported by encoder factory."; 805b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 806b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_codec_.Set(supported_codecs.front()); 809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 811d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 812d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 813d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 814d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 815d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org assert(it->second != NULL); 816d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetCodec(supported_codecs.front()); 817d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 823b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodecSettings codec_settings; 824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 827b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *codec = codec_settings.codec; 829b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 830b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 831b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 832b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, 833b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 834b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 835b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 836b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 837b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 838b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 839b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 840b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 841b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRender(bool render) { 843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. 844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); 845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send && !send_codec_.IsSet()) { 851b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 853b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 855b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 856b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 857b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 858b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 859b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 860b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 861b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 862b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 863b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 864b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sp.ssrcs.empty()) { 866b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No SSRCs in stream parameters."; 867b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 868b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 869b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 871b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Make sure none of sp.ssrcs are used, not just the identifying 873b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ssrc. 874b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) != send_streams_.end()) { 875b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Send stream with ssrc '" << ssrc << "' already exists."; 876b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 877b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 878b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 8795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> primary_ssrcs; 8805301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(&primary_ssrcs); 8815301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> rtx_ssrcs; 8825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(primary_ssrcs, &rtx_ssrcs); 8835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 8845301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_ERROR) 8855301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 8865301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << sp.ToString(); 887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoSendStream* stream = 8916ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org new WebRtcVideoSendStream(call_.get(), 8925301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org encoder_factory_, 8936ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options_, 8945301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_codec_, 8955301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp, 8965301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_rtp_extensions_); 8975301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 898b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 905b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 907b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 908b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 909b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 910b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 911b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 912b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 913b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { 914b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 915b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 916b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 917b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 918b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 919b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 920b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 921b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 922b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 923b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 924b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 925b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 926b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<uint32, WebRtcVideoSendStream*>::iterator it = 927b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.find(ssrc); 928b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (it == send_streams_.end()) { 929b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 930b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 931b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 932b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 933b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.erase(it); 934b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 935b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 936b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 937b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 938b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 939b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 940b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 941b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 942b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 943b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); 944b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(sp.ssrcs.size() > 0); 945b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 946b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 947b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); // TODO(pbos): Is this ever valid? 948b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 949b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Check if any of the SSRCs overlap. 950b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (receive_streams_.find(ssrc) != receive_streams_.end()) { 951b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Receive stream for SSRC " << ssrc << "already exists."; 952b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 953b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 954b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 955bd249bc711b3c9efd142eb8de3df489282fe693epbos@webrtc.org webrtc::VideoReceiveStream::Config config; 956d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ConfigureReceiverRtp(&config, sp); 957d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_[ssrc] = 958d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org new WebRtcVideoReceiveStream(call_.get(), config, recv_codecs_); 959d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 960d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 961d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 962d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 963d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 964d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 965d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const StreamParams& sp) const { 966d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 967d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 968d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remote_ssrc = ssrc; 969d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 970b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 971d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 972257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 973b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 974b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 975b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 976b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 977d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 978d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 979d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 980b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 981d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 982b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 983b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 984b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 985d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 986d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (recv_codecs_[i].codec.id == kDefaultVideoCodecPref.payload_type) { 987d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.fec = recv_codecs_[i].fec; 988d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 rtx_ssrc; 989d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 990d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 991d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].ssrc = rtx_ssrc; 992d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].payload_type = 993d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org recv_codecs_[i].rtx_payload_type; 994b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 995d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org break; 996b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 997b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 998b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 999b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1000b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1001b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { 1002b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 1003b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1004afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 1005afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return false; 1006b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1007b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1008d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator stream = 1009b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 1010b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 1011b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 1012b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1013b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1014d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org delete stream->second; 1015b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 1016b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1017b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1018b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1019b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1020b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 1021b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 1022b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 1023b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1024afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_unsignalled_ssrc_handler_.SetDefaultRenderer(this, renderer); 1025d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1026b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1027b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1028d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1029d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1030d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1031d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return false; 1032b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1033b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1034b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1035b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1036b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1037b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1038b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { 1039b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1040afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org *renderer = default_unsignalled_ssrc_handler_.GetDefaultRenderer(); 1041afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return *renderer != NULL; 1042b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1043b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1044d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1045d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1046d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1047b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1048b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1049b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1050b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1051b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1052b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1053b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(const StatsOptions& options, 1054b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoMediaInfo* info) { 1055e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info->Clear(); 1056e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillSenderStats(info); 1057e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillReceiverStats(info); 1058e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillBandwidthEstimationStats(info); 1059b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1060b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1061b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1062e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 1063e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1064e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org send_streams_.begin(); 1065e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != send_streams_.end(); 1066e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1067e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 1068e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1069e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1070e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1071e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 1072e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1073e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org receive_streams_.begin(); 1074e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != receive_streams_.end(); 1075e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1076e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 1077e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1078e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1079e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1080e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 1081e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoMediaInfo* video_media_info) { 1082e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Implement. 1083e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1084e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1085b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 1086b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1087b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 1088b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1089b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1090b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1091b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1092b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1093b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetCapturer(capturer); 1094b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1095b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1096b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1097b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1098b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1099b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1100b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1101b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1102b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1103b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1105b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1106b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1108b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1109d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1110d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11114e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 11124e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org call_->Receiver()->DeliverPacket( 11134e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()); 11144e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 11154e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 11164e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11174e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 11184e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11194e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 11204e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = 0; 1124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!GetRtpSsrc(packet->data(), packet->length(), &ssrc)) { 1125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1128afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org // TODO(pbos): Make sure that the unsignalled SSRC uses the video payload. 1129afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org // Also figure out whether RTX needs to be handled. 1130afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 1131afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDropPacket: 1132afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return; 1133afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDeliverPacket: 1134afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org break; 1135afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 1136b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 11371e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 11381e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 11391e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1140afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; 1141b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1142b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1143b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1144b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1145b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1146d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1147d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11481e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 11491e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 11501e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1151b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTCP packet."; 1152b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1153b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1154b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1155b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 1156b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "OnReadySend: " << (ready ? "Ready." : "Not ready."); 1157b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1158b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1159b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { 1160b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1161b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 1162b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1167ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org 1168ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org send_streams_[ssrc]->MuteStream(mute); 1169ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org return true; 1170b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1171b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1172b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1173b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1174587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " 1175587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 11763c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 11773c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1178d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 11793c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org recv_rtp_extensions_ = FilterRtpExtensions(extensions); 1180d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1181d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 1182d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 1183d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1184d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 1185d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1188b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1189b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1190b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1191587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " 1192587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 11933c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 11943c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 11953c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 11963c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org send_rtp_extensions_ = FilterRtpExtensions(extensions); 1197d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1198d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 1199d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 1200d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1201d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 1202d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1203b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1204b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1205b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1206b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetStartSendBandwidth(int bps) { 1207b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1208b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetStartSendBandwidth: " << bps; 1209b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1210b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1211b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1212b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int bps) { 1213b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1214b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetMaxSendBandwidth: " << bps; 1215b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1216b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1217b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1218b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 1219b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); 1220b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 12215301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 12225301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_streams_.begin(); 12235301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it != send_streams_.end(); 12245301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ++it) { 12255301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it->second->SetOptions(options_); 12265301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1227b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1228b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1229b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1230b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1231b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1232b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1233b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1234d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Socket::OPT_RCVBUF, 1235b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1236b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1237b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(sriniv): Remove or re-enable this. 1238b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // As part of b/8030474, send-buffer is size now controlled through 1239b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // portallocator flags. 1240b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // network_interface_->SetOption(NetworkInterface::ST_RTP, 1241d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org // rtc::Socket::OPT_SNDBUF, 1242b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // kVideoRtpBufferSize); 1243b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1244b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1245b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1246b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1247b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1248b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1249d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(rtc::Message* msg) { 1250b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1251b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1253b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { 1254d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1255b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendPacket(&packet); 1256b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1257b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1258b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1259d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1260b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendRtcp(&packet); 1261b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1262b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1263b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1264b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1265b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1266b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1267b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1268b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1269b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1270b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1271b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1272b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1273b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1274b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1275b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1276b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1277b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1278b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1279b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1280b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 12816ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 12826ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 12836ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 12846ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 12855301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings) 12865301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org : config(config), options(options), codec_settings(codec_settings) { 12876ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org} 12886ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 1289b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1290b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 12915301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory, 12926ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 12935301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings, 12945301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const StreamParams& sp, 12955301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) 1296b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : call_(call), 1297b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org encoder_factory_(encoder_factory), 1298b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 1299b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org parameters_(webrtc::VideoSendStream::Config(), options, codec_settings), 1300b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org capturer_(NULL), 1301b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 13025301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org muted_(false) { 13035301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 13045301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13055301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 13065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 13075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 13085301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 13095301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 13105301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13115301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings params; 13125301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (codec_settings.Get(¶ms)) { 13135301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodec(params); 13145301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1316b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1317b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1318b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 13195301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 13205301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org call_->DestroyVideoSendStream(stream_); 13215301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 13226ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org delete parameters_.config.encoder_settings.encoder; 1323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void SetWebRtcFrameToBlack(webrtc::I420VideoFrame* video_frame) { 1326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(video_frame != NULL); 1327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 1328b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 16, 1329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 1331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1332b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1333b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 1334b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1335b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1336b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void CreateBlackFrame(webrtc::I420VideoFrame* video_frame, 1339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->CreateEmptyFrame( 1342b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org width, height, width, (width + 1) / 2, (width + 1) / 2); 1343b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetWebRtcFrameToBlack(video_frame); 1344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1345b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void ConvertToI420VideoFrame(const VideoFrame& frame, 1347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::I420VideoFrame* i420_frame) { 1348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org i420_frame->CreateFrame( 1349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch() * frame.GetHeight()), 1350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetYPlane(), 1351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch() * ((frame.GetHeight() + 1) / 2)), 1352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetUPlane(), 1353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch() * ((frame.GetHeight() + 1) / 2)), 1354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetVPlane(), 1355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetWidth()), 1356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetHeight()), 1357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch()), 1358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch()), 1359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch())); 1360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 1365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "InputFrame: " << frame->GetWidth() << "x" 1366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << frame->GetHeight(); 1367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org bool is_screencast = capturer->IsScreencast(); 1368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock before copying, can be called concurrently when swapping input source. 1369d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope frame_cs(&frame_lock_); 1370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!muted_) { 1371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ConvertToI420VideoFrame(*frame, &video_frame_); 1372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Create a tiny black frame to transmit instead. 1374b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org CreateBlackFrame(&video_frame_, 1, 1); 1375b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org is_screencast = false; 1376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1377d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 13785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ == NULL) { 13795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_WARNING) << "Capturer inputting frames before send codecs are " 13805301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org "configured, dropping."; 13815301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org return; 13825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 1384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(format_.height == 0); 1385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1387b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1388b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1389b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (is_screencast) { 1390b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetDimensions(video_frame_.width(), video_frame_.height()); 1391b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1392b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SwapFrame: " << video_frame_.width() << "x" 1393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << video_frame_.height() << " -> (codec) " 13946ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.video_streams.back().width << "x" 13956ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.video_streams.back().height; 1396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Input()->SwapFrame(&video_frame_); 1397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1398b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1399b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1400b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1403b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1404b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1405b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1406d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14089359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (capturer == NULL) { 14099359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (stream_ != NULL) { 14109359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 14119359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org webrtc::I420VideoFrame black_frame; 14129359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org 14139359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int width = format_.width; 14149359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int height = format_.height; 14159359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int half_width = (width + 1) / 2; 14169359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org black_frame.CreateEmptyFrame( 14179359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org width, height, width, half_width, half_width); 14189359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org SetWebRtcFrameToBlack(&black_frame); 14199359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org SetDimensions(width, height); 14209359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org stream_->Input()->SwapFrame(&black_frame); 14219359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org } 1422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1423b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1424b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1431b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1444d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1445b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1446b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 14486ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 14516ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().max_framerate = 1452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetDimensions(format.width, format.height); 1454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1460ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1461d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1462b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1466d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (capturer_ == NULL) { 1468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_->SignalVideoFrame.disconnect(this); 1471b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 14765301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1477d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 14785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings codec_settings; 14795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (parameters_.codec_settings.Get(&codec_settings)) { 14805301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, options); 14815301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } else { 14825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.options = options; 14835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 14845301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 1485b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 14865301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings) { 1487d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 14885301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 14895301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 14905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 14915301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings, 14925301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 14936ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org std::vector<webrtc::VideoStream> video_streams = 14946ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org encoder_factory_->CreateVideoStreams( 14955301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec, options, parameters_.config.rtp.ssrcs.size()); 14966ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (video_streams.empty()) { 1497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 14996ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams = video_streams; 15005301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 15015301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec.height, 1502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 1503b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 15046ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15056ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org webrtc::VideoEncoder* old_encoder = 15066ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config.encoder_settings.encoder; 15076ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config.encoder_settings.encoder = 15085301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org encoder_factory_->CreateVideoEncoder(codec_settings.codec, options); 15095301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 15105301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 15115301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 15125301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15135301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org // Set RTX payload type if RTX is enabled. 15145301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 15155301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 1516543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1517543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org options.use_payload_padding.Get( 1518543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org ¶meters_.config.rtp.rtx.pad_with_redundant_payloads); 15195301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15205301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15215301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (IsNackEnabled(codec_settings.codec)) { 15225301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.nack.rtp_history_ms = kNackHistoryMs; 15235301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15245301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15255ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options.suspend_below_min_bitrate.Get( 15265ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org ¶meters_.config.suspend_below_min_bitrate); 15275ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org 15285301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.codec_settings.Set(codec_settings); 15296ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 1530543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 1532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete old_encoder; 1533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1535d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 1536d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 1537d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1538d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 1539d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1540d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1541d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1542b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions(int width, 15436ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org int height) { 15446ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org assert(!parameters_.video_streams.empty()); 1545b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height; 15466ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (parameters_.video_streams.back().width == width && 15476ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().height == height) { 1548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 15526ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().width = width; 15536ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().height = height; 15546ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15556f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 15566f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 15576f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org void* encoder_settings = encoder_factory_->CreateVideoEncoderSettings( 15586f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org codec_settings.codec, parameters_.options); 15596f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 15606f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder( 15616f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.video_streams, encoder_settings); 15626f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 15636f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings(codec_settings.codec, 15646f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_settings); 15656f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 15666f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (!stream_reconfigured) { 1567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 1568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 1569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 1574d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 15755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org assert(stream_ != NULL); 1576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 1578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 1581d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 15825301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 15835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org stream_->Stop(); 15845301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1585b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 1586b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1587b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1588e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoSenderInfo 1589e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 1590e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoSenderInfo info; 1591d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1592e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (size_t i = 0; i < parameters_.config.rtp.ssrcs.size(); ++i) { 1593e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(parameters_.config.rtp.ssrcs[i]); 1594e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1595e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1596c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org if (stream_ == NULL) { 1597c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org return info; 1598c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org } 1599c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org 1600e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 1601e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_input = stats.input_frame_rate; 1602e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 1603e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1604e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32_t, webrtc::StreamStats>::iterator it = 1605e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.substreams.begin(); 1606e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != stats.substreams.end(); 1607e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1608e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 1609e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::StreamStats stream_stats = it->second; 1610e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.bytes_sent += stream_stats.rtp_stats.bytes + 1611e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stream_stats.rtp_stats.header_bytes + 1612e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stream_stats.rtp_stats.padding_bytes; 1613e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_sent += stream_stats.rtp_stats.packets; 1614e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 1615e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1616e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1617e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (!stats.substreams.empty()) { 1618e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 1619e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::StreamStats first_stream_stats = stats.substreams.begin()->second; 1620e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.fraction_lost = 1621e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 1622e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org (1 << 8); 1623e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1624e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1625e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (capturer_ != NULL && !capturer_->IsMuted()) { 1626e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoFormat last_captured_frame_format; 1627e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, 1628e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &info.effects_frame_drops, 1629e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &info.capturer_frame_time, 1630e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &last_captured_frame_format); 1631e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 1632e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 1633e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.send_frame_width = 1634e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<int>(parameters_.video_streams.front().width); 1635e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.send_frame_height = 1636e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<int>(parameters_.video_streams.front().height); 1637e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1638e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1639e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Support or remove the following stats. 1640e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_cached = -1; 1641e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.rtt_ms = -1; 1642e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1643e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 1644e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1645e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 1647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 1648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 1649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 16506ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 16516f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 16526f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 16536f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org void* encoder_settings = encoder_factory_->CreateVideoEncoderSettings( 16546f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org codec_settings.codec, parameters_.options); 16556f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 16566ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org stream_ = call_->CreateVideoSendStream( 16576f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.config, parameters_.video_streams, encoder_settings); 16586f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 16596f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings(codec_settings.codec, 16606f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_settings); 16616f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 1663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1667d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 1668d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::Call* call, 1669d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::VideoReceiveStream::Config& config, 1670d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) 1671d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org : call_(call), 1672d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_(NULL), 1673b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org config_(config), 1674b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org renderer_(NULL), 1675d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_(-1), 1676b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org last_height_(-1) { 1677d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.renderer = this; 1678d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 1679d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRecvCodecs(recv_codecs); 1680d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1681d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1682d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 1683d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1684d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1685d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1686d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 1687d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 1688d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 1689d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Base receive codecs off recv_codecs_ and set up using a 1690d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // DecoderFactory similar to send side. Pending webrtc:2854. 1691d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // Also set up default codecs if there's nothing in recv_codecs_. 1692d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoCodec codec; 1693d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org memset(&codec, 0, sizeof(codec)); 1694d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1695d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.plType = kDefaultVideoCodecPref.payload_type; 1696d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org strcpy(codec.plName, kDefaultVideoCodecPref.name); 1697d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecType = webrtc::kVideoCodecVP8; 1698d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.resilience = webrtc::kResilientStream; 1699d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.numberOfTemporalLayers = 1; 1700d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.denoisingOn = true; 1701d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.errorConcealmentOn = false; 1702d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.automaticResizeOn = false; 1703d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.frameDroppingOn = true; 1704d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.keyFrameInterval = 3000; 1705d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // Bitrates don't matter and are ignored for the receiver. This is put in to 1706d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // have the current underlying implementation accept the VideoCodec. 1707d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.minBitrate = codec.startBitrate = codec.maxBitrate = 300; 1708d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.codecs.clear(); 1709d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.codecs.push_back(codec); 1710d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1711d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 1712d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1713257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.nack.rtp_history_ms = 1714257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org IsNackEnabled(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 1715257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.remb = IsRembEnabled(recv_codecs.begin()->codec); 1716257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 1717d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1718d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1719d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1720d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 1721d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 1722d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.extensions = extensions; 1723d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1724d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1725d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1726d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 1727d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (stream_ != NULL) { 1728d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1729d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1730d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 1731d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_->Start(); 1732d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1733d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1734d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 1735d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::I420VideoFrame& frame, 1736d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int time_to_render_ms) { 1737d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1738d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ == NULL) { 1739d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 1740d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return; 1741d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1742d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1743d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 1744d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(frame.width(), frame.height()); 1745d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1746d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1747d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_VERBOSE) << "RenderFrame: (" << frame.width() << "x" << frame.height() 1748d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org << ")"; 1749d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1750d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const WebRtcVideoRenderFrame render_frame(&frame); 1751d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_->RenderFrame(&render_frame); 1752d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1753d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1754d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 1755d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org cricket::VideoRenderer* renderer) { 1756d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1757d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_ = renderer; 1758d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 1759d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(last_width_, last_height_); 1760d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1761d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1762d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1763d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 1764d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 1765d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // design. 1766d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1767d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return renderer_; 1768d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1769d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1770d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 1771d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int height) { 1772d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1773d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 1774d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 1775d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1776d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_ = width; 1777d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_ = height; 1778d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1779d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1780e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoReceiverInfo 1781e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 1782e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoReceiverInfo info; 1783e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 1784e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 1785e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.bytes_rcvd = stats.rtp_stats.bytes + stats.rtp_stats.header_bytes + 1786e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.rtp_stats.padding_bytes; 1787e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_rcvd = stats.rtp_stats.packets; 1788e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1789e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 1790e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 1791e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_output = stats.render_frame_rate; 1792e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1793d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope frame_cs(&renderer_lock_); 1794e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.frame_width = last_width_; 1795e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.frame_height = last_height_; 1796e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1797e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Support or remove the following stats. 1798e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_concealed = -1; 1799e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1800e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 1801e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1802e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 1804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 1805b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1806b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 1807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 1808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!codecs.empty()); 1809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 1811b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 1812e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 1813b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, int> rtx_mapping; // video payload type -> rtx payload type. 1814b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1815b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 1816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 1818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 1819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 1820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 1822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 1823b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 1824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 1827e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 1828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1829b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 1830b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 1831b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 1832b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.red_payload_type == -1); 1833b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 1834b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1835b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1836b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1837b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 1838b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 1839b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.ulpfec_payload_type == -1); 1840b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 1841b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 1845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 1846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 1847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org &associated_payload_type)) { 1848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RTX codec without associated payload type: " 1849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 1850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1851b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 1853b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1855b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1856b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 1857b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 1858b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1859b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1860b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 1861b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 1862b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1863b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1864b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 1865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 1866b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!video_codecs.empty()); 1867b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1868e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 1869e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org it != rtx_mapping.end(); 1870e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org ++it) { 1871e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!payload_used[it->first]) { 1872e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 1873e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1874e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1875e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO) { 1876e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX not mapped to regular video codec."; 1877e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1878e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1879e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1880e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 1881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Write tests that figure out that I have not verified that RTX 1882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // codecs aren't mapped to bogus payloads. 1883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 1884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 1885b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtx_mapping[video_codecs[i].codec.id] != 0) { 1886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 1887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 1891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 1894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 1895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) { 1896b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 1897b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 1898b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (encoder_factory_->SupportsCodec(mapped_codecs[i].codec)) { 1899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org supported_codecs.push_back(mapped_codecs[i]); 1900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return supported_codecs; 1903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1905b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 1906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1907b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 1908