webrtcvideoengine2.cc revision 0a2087a7110e2455ce68f2c85068df5ae447508f
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" 45ab990ae43a2b84b103cb3c50bc38502375c13e68pbos@webrtc.org#include "webrtc/video_encoder.h" 46b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 47b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#define UNIMPLEMENTED \ 48b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Call to unimplemented function " << __FUNCTION__; \ 49b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(false) 50b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 51b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace cricket { 52b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 53b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 54b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// duration hasn't been implemented. 55b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 56b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 57933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.orgstatic const int kDefaultQpMax = 56; 58933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org 59b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 60b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 61b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstruct VideoCodecPref { 62b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type; 6397fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org int width; 6497fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org int height; 65b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const char* name; 66b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rtx_payload_type; 6797fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org} kDefaultVideoCodecPref = {100, 640, 400, kVp8CodecName, 96}; 68b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 6997fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.orgVideoCodecPref kRedPref = {116, -1, -1, kRedCodecName, -1}; 7097fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.orgVideoCodecPref kUlpfecPref = {117, -1, -1, kUlpfecCodecName, -1}; 71b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 72b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 73b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& requested_codec, 74b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* matching_codec) { 75b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 76b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 77b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *matching_codec = codecs[i]; 78b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 79b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 80b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 81b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 82b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 83b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 84f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.orgstatic void AddDefaultFeedbackParams(VideoCodec* codec) { 85f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kFir(kRtcpFbParamCcm, kRtcpFbCcmParamFir); 86f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kFir); 87f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kNack(kRtcpFbParamNack, kParamValueEmpty); 88f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kNack); 89f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kPli(kRtcpFbParamNack, kRtcpFbNackParamPli); 90f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kPli); 91f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kRemb(kRtcpFbParamRemb, kParamValueEmpty); 92f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kRemb); 93f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org} 94f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org 95f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.orgstatic bool IsNackEnabled(const VideoCodec& codec) { 96f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org return codec.HasFeedbackParam( 97f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); 98f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org} 99f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org 100257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.orgstatic bool IsRembEnabled(const VideoCodec& codec) { 101257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org return codec.HasFeedbackParam( 102257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); 103257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org} 104257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 105b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultVideoCodec() { 106b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec default_codec(kDefaultVideoCodecPref.payload_type, 107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.name, 10897fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org kDefaultVideoCodecPref.width, 10997fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.org kDefaultVideoCodecPref.height, 110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultFramerate, 111b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 0); 112f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org AddDefaultFeedbackParams(&default_codec); 113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return default_codec; 114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultRedCodec() { 117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kRedPref.payload_type, kRedPref.name, 0, 0, 0, 0); 118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultUlpfecCodec() { 121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kUlpfecPref.payload_type, kUlpfecPref.name, 0, 0, 0, 0); 122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic std::vector<VideoCodec> DefaultVideoCodecs() { 125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodec> codecs; 126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultVideoCodec()); 127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultRedCodec()); 128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultUlpfecCodec()); 129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (kDefaultVideoCodecPref.rtx_payload_type != -1) { 130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back( 131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec::CreateRtxCodec(kDefaultVideoCodecPref.rtx_payload_type, 132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.payload_type)); 133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return codecs; 135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 136b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1373c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic bool ValidateRtpHeaderExtensionIds( 1383c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1393c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::set<int> extensions_used; 1403c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1413c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (extensions[i].id < 0 || extensions[i].id >= 15 || 1423c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org !extensions_used.insert(extensions[i].id).second) { 1433c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; 1443c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1453c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1463c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1473c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return true; 1483c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 1493c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1503c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic std::vector<webrtc::RtpExtension> FilterRtpExtensions( 1513c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1523c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::vector<webrtc::RtpExtension> webrtc_extensions; 1533c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1543c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org // Unsupported extensions will be ignored. 1553c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (webrtc::RtpExtension::IsSupported(extensions[i].uri)) { 1563c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org webrtc_extensions.push_back(webrtc::RtpExtension( 1573c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org extensions[i].uri, extensions[i].id)); 1583c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } else { 1593c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; 1603c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1613c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1623c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return webrtc_extensions; 1633c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 1643c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1650d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.orgWebRtcVideoEncoderFactory2::~WebRtcVideoEncoderFactory2() { 1660d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org} 1670d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org 168d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgstd::vector<webrtc::VideoStream> WebRtcVideoEncoderFactory2::CreateVideoStreams( 169d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 170d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 171d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 172d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org assert(SupportsCodec(codec)); 173d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org if (num_streams != 1) { 174d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org LOG(LS_ERROR) << "Unsupported number of streams: " << num_streams; 175d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return std::vector<webrtc::VideoStream>(); 1766ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org } 177b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 178d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 179d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 180d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 181d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 182d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultFramerate; 183d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 184d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int min_bitrate = kMinVideoBitrate; 185d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMinBitrate, &min_bitrate); 186d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int max_bitrate = kMaxVideoBitrate; 187d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxBitrate, &max_bitrate); 188d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.min_bitrate_bps = min_bitrate * 1000; 189d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate * 1000; 190d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 191933d88af58b00517570ef78f38852bfd7fb1bb02buildbot@webrtc.org int max_qp = kDefaultQpMax; 192d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 193d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 194d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 195d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 196d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 197d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 198b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 199d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgwebrtc::VideoEncoder* WebRtcVideoEncoderFactory2::CreateVideoEncoder( 200d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 201d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options) { 202d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org assert(SupportsCodec(codec)); 2036f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 204ab990ae43a2b84b103cb3c50bc38502375c13e68pbos@webrtc.org return webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8); 2056f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2066f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org // This shouldn't happen, we should be able to create encoders for all codecs 2076f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org // we support. 2086f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(false); 2096f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 2106f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 2116f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2126f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid* WebRtcVideoEncoderFactory2::CreateVideoEncoderSettings( 2136f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 2146f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoOptions& options) { 2156f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(SupportsCodec(codec)); 2166f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2176cd6ba8ae016200a7a13b43294b8faf5d1d4affdpbos@webrtc.org webrtc::VideoCodecVP8* settings = new webrtc::VideoCodecVP8( 2186cd6ba8ae016200a7a13b43294b8faf5d1d4affdpbos@webrtc.org webrtc::VideoEncoder::GetDefaultVp8Settings()); 2196f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org options.video_noise_reduction.Get(&settings->denoisingOn); 2206f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return settings; 2216f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2226f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 2236f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 2246f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2256f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoEncoderFactory2::DestroyVideoEncoderSettings( 2266f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 2276f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org void* encoder_settings) { 2286f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(SupportsCodec(codec)); 2296f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (encoder_settings == NULL) { 2306f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return; 2316f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2326f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2336f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org delete reinterpret_cast<webrtc::VideoCodecVP8*>(encoder_settings); 2346f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 235d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 236d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 237d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgbool WebRtcVideoEncoderFactory2::SupportsCodec(const VideoCodec& codec) { 238df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org return _stricmp(codec.name.c_str(), kVp8CodecName) == 0; 239d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 240b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 241afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgDefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler() 242afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org : default_recv_ssrc_(0), default_renderer_(NULL) {} 243afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 244afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgUnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc( 245afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 246afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org uint32_t ssrc) { 247afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 248afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 249afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDropPacket; 250afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 251afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 252afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org StreamParams sp; 253afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org sp.ssrcs.push_back(ssrc); 254afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 255afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (!channel->AddRecvStream(sp)) { 256afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Could not create default receive stream."; 257afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 258afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 259afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(ssrc, default_renderer_); 260afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_recv_ssrc_ = ssrc; 261afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return kDeliverPacket; 262afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 263afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 264afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgVideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { 265afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return default_renderer_; 266afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 267afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 268afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.orgvoid DefaultUnsignalledSsrcHandler::SetDefaultRenderer( 269afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoMediaChannel* channel, 270afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org VideoRenderer* renderer) { 271afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_renderer_ = renderer; 272afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org if (default_recv_ssrc_ != 0) { 273afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org channel->SetRenderer(default_recv_ssrc_, default_renderer_); 274afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 275afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org} 276afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org 27797fdeb8329cf5c328fa531c0a61c3dd181eb4833pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2() 278b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : worker_thread_(NULL), 279b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org voice_engine_(NULL), 280b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org video_codecs_(DefaultVideoCodecs()), 281992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org default_codec_format_(kDefaultVideoCodecPref.width, 282992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org kDefaultVideoCodecPref.height, 283992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org FPS_TO_INTERVAL(kDefaultFramerate), 284992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org FOURCC_ANY), 285b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org initialized_(false), 286b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org cpu_monitor_(new rtc::CpuMonitor(NULL)), 2870a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org channel_factory_(NULL), 2880a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_(NULL), 2890a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_(NULL) { 290b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; 291587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 292587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 293587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpTimestampOffsetHeaderExtensionDefaultId)); 294587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 295587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 296587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 297b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 298b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 299b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.orgvoid WebRtcVideoEngine2::SetChannelFactory( 300b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org WebRtcVideoChannelFactory* channel_factory) { 301b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org channel_factory_ = channel_factory; 302b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org} 303b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org 304b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 307b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 308b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Terminate(); 309b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 311b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 312d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgbool WebRtcVideoEngine2::Init(rtc::Thread* worker_thread) { 313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org worker_thread_ = worker_thread; 315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(worker_thread_ != NULL); 316b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 317b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->set_thread(worker_thread_); 318b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!cpu_monitor_->Start(kCpuMonitorPeriodMs)) { 319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Failed to start CPU monitor."; 320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_.reset(); 321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::Terminate() { 328b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Terminate"; 329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->Stop(); 331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 332b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = false; 333b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 334b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 335b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgint WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } 336b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoEncoderConfig& config) { 3398fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org const VideoCodec& codec = config.max_codec; 3408fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org // TODO(pbos): Make use of external encoder factory. 3418fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (!GetVideoEncoderFactory()->SupportsCodec(codec)) { 3428fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported:" 3438fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org << codec.ToString(); 3448fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return false; 3458fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 3468fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 347992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org default_codec_format_ = 348992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org VideoFormat(codec.width, 349992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org codec.height, 350992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org VideoFormat::FpsToInterval(codec.framerate), 351992febb9978d2ded1a2c3c8a42ea18ee071ca3aebuildbot@webrtc.org FOURCC_ANY); 3528fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org video_codecs_.clear(); 3538fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org video_codecs_.push_back(codec); 354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoEncoderConfig WebRtcVideoEngine2::GetDefaultEncoderConfig() const { 358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoEncoderConfig(DefaultVideoCodec()); 359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel) { 363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "CreateChannel: " 364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (voice_channel != NULL ? "With" : "Without") 365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << " voice channel."; 366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoChannel2* channel = 367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org channel_factory_ != NULL 368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ? channel_factory_->Create(this, voice_channel) 369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : new WebRtcVideoChannel2( 3700d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org this, voice_channel, GetVideoEncoderFactory()); 371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!channel->Init()) { 372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete channel; 373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 374b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 375e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org channel->SetRecvCodecs(video_codecs_); 376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return channel; 377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 379b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return rtp_header_extensions_; 386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 387b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 388b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { 389b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Set up logging. 390b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; 391b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if min_sev == -1, we keep the current log level. 392b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (min_sev < 0) { 393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(min_sev == -1); 394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 395b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 3980a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalDecoderFactory( 3990a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoDecoderFactory* decoder_factory) { 4000a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_decoder_factory_ = decoder_factory; 4010a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 4020a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 4030a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::SetExternalEncoderFactory( 4040a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org WebRtcVideoEncoderFactory* encoder_factory) { 4050a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org if (external_encoder_factory_ == encoder_factory) { 4060a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org return; 4070a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org } 4080a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org if (external_encoder_factory_) { 4090a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_->RemoveObserver(this); 4100a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org } 4110a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_ = encoder_factory; 4120a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org if (external_encoder_factory_) { 4130a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org external_encoder_factory_->AddObserver(this); 4140a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org } 4150a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 4160a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org // Invoke OnCodecAvailable() here in case the list of codecs is already 4170a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org // available when the encoder factory is installed. If not the encoder 4180a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org // factory will invoke the callback later when the codecs become available. 4190a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org OnCodecsAvailable(); 4200a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 4210a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org 422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 423b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 424b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 431b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 4328fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 4338fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 4348fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (codec.Matches(in)) { 4358fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 444b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// dimensions will be used for aspect ratio matching. 445b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 446b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& current, 447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* out) { 448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(out != NULL); 449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width != requested.height && 451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // 0xn and nx0 are invalid resolutions. 453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec matching_codec; 457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Codec not supported. 459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 460b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 461b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 462b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->id = requested.id; 463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->name = requested.name; 464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->preference = requested.preference; 465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 466b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->framerate = 467d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::_min(requested.framerate, matching_codec.framerate); 468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->feedback_params = requested.feedback_params; 4708fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width = requested.width; 4718fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height = requested.height; 4728fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 4738fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 4748fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 4758fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 4768fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org while (out->width > matching_codec.width) { 4778fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width /= 2; 4788fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height /= 2; 4798fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 4808fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 4818fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return out->width > 0 && out->height > 0; 482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 483b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 484b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetVoiceEngine(WebRtcVoiceEngine* voice_engine) { 485b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 486b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "SetVoiceEngine can not be called after Init"; 487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org voice_engine_ = voice_engine; 490b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 491b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 496b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 503b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 504b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 505d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgWebRtcVideoEncoderFactory2* WebRtcVideoEngine2::GetVideoEncoderFactory() { 506d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return &default_video_encoder_factory_; 507b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 508b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 5090a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.orgvoid WebRtcVideoEngine2::OnCodecsAvailable() { 5100a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org // TODO(pbos): Implement. 5110a2087a7110e2455ce68f2c85068df5ae447508fpbos@webrtc.org} 5126ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org// Thin map between VideoFrame and an existing webrtc::I420VideoFrame 513b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// to avoid having to copy the rendered VideoFrame prematurely. 514b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This implementation is only safe to use in a const context and should never 515b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be written to. 5166ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgclass WebRtcVideoRenderFrame : public VideoFrame { 517b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org public: 518b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org explicit WebRtcVideoRenderFrame(const webrtc::I420VideoFrame* frame) 519b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : frame_(frame) {} 520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool InitToBlack(int w, 522b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 523b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 525b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) OVERRIDE { 527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 529b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 530b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool Reset(uint32 fourcc, 532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int w, 533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dw, 535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dh, 536b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* sample, 537b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t sample_size, 538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 539b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 540b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 541b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp, 542b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rotation) OVERRIDE { 543b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 544b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 545b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 546b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 547b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetWidth() const OVERRIDE { 548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->width()); 549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetHeight() const OVERRIDE { 551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->height()); 552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 554b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetYPlane() const OVERRIDE { 555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kYPlane); 556b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 557b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetUPlane() const OVERRIDE { 558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kUPlane); 559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 560b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetVPlane() const OVERRIDE { 561b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kVPlane); 562b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 563b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 564b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetYPlane() OVERRIDE { 565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 566b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetUPlane() OVERRIDE { 569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetVPlane() OVERRIDE { 573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetYPitch() const OVERRIDE { 578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kYPlane); 579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetUPitch() const OVERRIDE { 581b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kUPlane); 582b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 583b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetVPitch() const OVERRIDE { 584b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kVPlane); 585b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 586b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 587b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void* GetNativeHandle() const OVERRIDE { return NULL; } 588b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 589b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelWidth() const OVERRIDE { return 1; } 590b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelHeight() const OVERRIDE { return 1; } 591b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 592b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetElapsedTime() const OVERRIDE { 593b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert millisecond render time to ns timestamp. 594d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org return frame_->render_time_ms() * rtc::kNumNanosecsPerMillisec; 595b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 596b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetTimeStamp() const OVERRIDE { 597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert 90K rtp timestamp to ns timestamp. 598d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org return (frame_->timestamp() / 90) * rtc::kNumNanosecsPerMillisec; 599b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 600b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetElapsedTime(int64 elapsed_time) OVERRIDE { UNIMPLEMENTED; } 601b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetTimeStamp(int64 time_stamp) OVERRIDE { UNIMPLEMENTED; } 602b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int GetRotation() const OVERRIDE { 604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 605b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return ROTATION_0; 606b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* Copy() const OVERRIDE { 609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool MakeExclusive() OVERRIDE { 614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 618b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t CopyToBuffer(uint8* buffer, size_t size) const { 619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; 621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(fbarchard): Refactor into base class and share with LMI 624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, 625b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* buffer, 626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t size, 627b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int stride_rgb) const OVERRIDE { 628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t width = GetWidth(); 629b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t height = GetHeight(); 630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t needed = (stride_rgb >= 0 ? stride_rgb : -stride_rgb) * height; 631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (size < needed) { 632b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "RGB buffer is not large enough"; 633b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 634b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 635b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 636b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (libyuv::ConvertFromI420(GetYPlane(), 637b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetYPitch(), 638b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPlane(), 639b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPitch(), 640b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPlane(), 641b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPitch(), 642b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org buffer, 643b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stride_rgb, 644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(width), 645b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(height), 646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org to_fourcc)) { 647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RGB type not supported: " << to_fourcc; 648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; // 0 indicates error 649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 650b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 651b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 653b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org protected: 654b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* CreateEmptyFrame(int w, 655b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 656b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 657b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 659b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) const OVERRIDE { 660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoFrame* frame = new WebRtcVideoFrame(); 661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame->InitToBlack( 662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org w, h, pixel_width, pixel_height, elapsed_time, time_stamp); 663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame; 664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org private: 667b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const webrtc::I420VideoFrame* const frame_; 668b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org}; 669b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 671b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine, 672b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel, 673b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 674b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 675b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org encoder_factory_(encoder_factory) { 676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Connect the video and audio with |voice_channel|. 677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call::Config config(this); 678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(webrtc::Call::Create(config), engine); 679b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine, 684b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 685b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), 686b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org encoder_factory_(encoder_factory) { 687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(call, engine); 688b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::Construct(webrtc::Call* call, 691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine) { 692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 693b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_.reset(call); 695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 6966f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 6976f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org SetDefaultOptions(); 6986f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 6996f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 7006f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 7016f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org options_.video_noise_reduction.Set(true); 702543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org options_.use_payload_padding.Set(false); 7035ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options_.suspend_below_min_bitrate.Set(false); 704b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 706b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 709b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 711b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 712b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 713b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 714d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 715b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.begin(); 716b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != receive_streams_.end(); 717b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 718b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 719b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 720b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 721b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 722b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::Init() { return true; } 723b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 724b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace { 725b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 726b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { 727b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::stringstream out; 728b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << '{'; 729b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 730b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << codecs[i].ToString(); 731b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (i != codecs.size() - 1) { 732b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << ", "; 733b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 734b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 735b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << '}'; 736b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return out.str(); 737b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 738b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 739e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.orgstatic bool ValidateCodecFormats(const std::vector<VideoCodec>& codecs) { 740e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org bool has_video = false; 741e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 742e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!codecs[i].ValidateCodecFormat()) { 743e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return false; 744e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 745e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (codecs[i].GetCodecType() == VideoCodec::CODEC_VIDEO) { 746e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org has_video = true; 747e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 748e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 749e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!has_video) { 750e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "Setting codecs without a video codec is invalid: " 751e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org << CodecVectorToString(codecs); 752e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return false; 753e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 754e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return true; 755e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org} 756e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 757587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.orgstatic std::string RtpExtensionsToString( 758587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 759587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org std::stringstream out; 760587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << '{'; 761587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 762587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; 763587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org if (i != extensions.size() - 1) { 764587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << ", "; 765587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org } 766587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org } 767587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << '}'; 768587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org return out.str(); 769587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org} 770587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org 771b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace 772b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 773b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 775b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 776b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 777b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 778b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 779b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 780b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 781b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without video codec payloads."; 782b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 783b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 784b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 785b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Add a decoder factory which controls supported codecs. 786b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Blocked on webrtc:2854. 787b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 788df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org if (_stricmp(mapped_codecs[i].codec.name.c_str(), kVp8CodecName) != 0) { 789b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported codec: '" 790b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << mapped_codecs[i].codec.name << "'"; 791b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 792b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 793b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 794b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 795b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org recv_codecs_ = mapped_codecs; 796d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 797d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 798d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 799d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 800d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 801d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 802d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 803d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 805b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 806b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 811b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 812b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 813b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 814b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 815b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No video codecs supported by encoder factory."; 818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_codec_.Set(supported_codecs.front()); 822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 823b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 824d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 825d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 826d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 827d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 828d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org assert(it->second != NULL); 829d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetCodec(supported_codecs.front()); 830d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 831b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 832b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 833b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 834b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 835b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 836b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodecSettings codec_settings; 837b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 838b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 839b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 840b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 841b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *codec = codec_settings.codec; 842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, 846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 851b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 853b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 855b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRender(bool render) { 856b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. 857b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); 858b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 859b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 860b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 861b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 862b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 863b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send && !send_codec_.IsSet()) { 864b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 866b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 867b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 868b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 869b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 871b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 873b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 874b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 875b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 876b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 877b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 878b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sp.ssrcs.empty()) { 879b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No SSRCs in stream parameters."; 880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 885b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Make sure none of sp.ssrcs are used, not just the identifying 886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ssrc. 887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) != send_streams_.end()) { 888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Send stream with ssrc '" << ssrc << "' already exists."; 889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 8925301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> primary_ssrcs; 8935301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(&primary_ssrcs); 8945301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> rtx_ssrcs; 8955301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(primary_ssrcs, &rtx_ssrcs); 8965301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 8975301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_ERROR) 8985301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 8995301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << sp.ToString(); 900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoSendStream* stream = 9046ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org new WebRtcVideoSendStream(call_.get(), 9055301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org encoder_factory_, 9066ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options_, 9075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_codec_, 9085301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp, 9095301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_rtp_extensions_); 9105301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 911b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 912b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 913b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 914b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 915b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 916b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 917b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 918b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 919b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 920b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 921b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 922b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 923b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 924b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 925b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 926b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { 927b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 928b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 929b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 930b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 931b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 932b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 933b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 934b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 935b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 936b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 937b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 938b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 939b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<uint32, WebRtcVideoSendStream*>::iterator it = 940b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.find(ssrc); 941b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (it == send_streams_.end()) { 942b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 943b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 944b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 945b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 946b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.erase(it); 947b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 948b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 949b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 950b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 951b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 952b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 953b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 954b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 955b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 956b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); 957b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(sp.ssrcs.size() > 0); 958b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 959b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 960b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); // TODO(pbos): Is this ever valid? 961b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 962b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Check if any of the SSRCs overlap. 963b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (receive_streams_.find(ssrc) != receive_streams_.end()) { 964b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Receive stream for SSRC " << ssrc << "already exists."; 965b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 966b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 967b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 968bd249bc711b3c9efd142eb8de3df489282fe693epbos@webrtc.org webrtc::VideoReceiveStream::Config config; 969d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ConfigureReceiverRtp(&config, sp); 970d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_[ssrc] = 971d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org new WebRtcVideoReceiveStream(call_.get(), config, recv_codecs_); 972d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 973d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 974d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 975d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 976d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 977d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 978d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const StreamParams& sp) const { 979d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 980d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 981d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remote_ssrc = ssrc; 982d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 983b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 984d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 985257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 986b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 987b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 988b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 989b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 990d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 991d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 992d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 993b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 994d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 995b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 996b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 997b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 998d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 999d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (recv_codecs_[i].codec.id == kDefaultVideoCodecPref.payload_type) { 1000d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.fec = recv_codecs_[i].fec; 1001d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 rtx_ssrc; 1002d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 1003d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 1004d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].ssrc = rtx_ssrc; 1005d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].payload_type = 1006d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org recv_codecs_[i].rtx_payload_type; 1007b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1008d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org break; 1009b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1010b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1011b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1012b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1013b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1014b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { 1015b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 1016b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1017afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 1018afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return false; 1019b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1020b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1021d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator stream = 1022b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 1023b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 1024b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 1025b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1026b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1027d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org delete stream->second; 1028b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 1029b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1030b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1031b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1032b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1033b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 1034b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 1035b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 1036b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1037afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org default_unsignalled_ssrc_handler_.SetDefaultRenderer(this, renderer); 1038d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1039b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1040b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1041d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1042d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1043d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1044d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return false; 1045b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1046b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1047b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1048b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1049b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1050b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1051b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { 1052b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1053afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org *renderer = default_unsignalled_ssrc_handler_.GetDefaultRenderer(); 1054afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return *renderer != NULL; 1055b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1056b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1057d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1058d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1059d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1060b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1061b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1062b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1063b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1064b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1065b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1066b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(const StatsOptions& options, 1067b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoMediaInfo* info) { 1068e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info->Clear(); 1069e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillSenderStats(info); 1070e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillReceiverStats(info); 1071e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillBandwidthEstimationStats(info); 1072b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1073b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1074b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1075e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 1076e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1077e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org send_streams_.begin(); 1078e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != send_streams_.end(); 1079e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1080e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 1081e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1082e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1083e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1084e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 1085e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1086e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org receive_streams_.begin(); 1087e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != receive_streams_.end(); 1088e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1089e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 1090e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1091e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1092e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1093e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 1094e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoMediaInfo* video_media_info) { 1095e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Implement. 1096e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1097e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1098b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 1099b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1100b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 1101b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1102b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1103b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1105b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1106b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetCapturer(capturer); 1107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1108b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1109b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1111b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1122d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1123d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11244e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 11254e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org call_->Receiver()->DeliverPacket( 11264e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()); 11274e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 11284e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 11294e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11304e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 11314e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11324e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 11334e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1136b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = 0; 1137b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!GetRtpSsrc(packet->data(), packet->length(), &ssrc)) { 1138b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1139b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1140b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1141afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org // TODO(pbos): Make sure that the unsignalled SSRC uses the video payload. 1142afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org // Also figure out whether RTX needs to be handled. 1143afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 1144afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDropPacket: 1145afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org return; 1146afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org case UnsignalledSsrcHandler::kDeliverPacket: 1147afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org break; 1148afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org } 1149b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 11501e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 11511e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 11521e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1153afb554f404d68e6f3ca5395216f776169370713dpbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet on re-delivery."; 1154b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1155b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1156b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1157b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1158b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1159d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer* packet, 1160d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org const rtc::PacketTime& packet_time) { 11611e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 11621e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 11631e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTCP packet."; 1165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1167b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1168b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 116926c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); 117026c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org call_->SignalNetworkState(ready ? webrtc::Call::kNetworkUp 117126c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org : webrtc::Call::kNetworkDown); 1172b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1173b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1174b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { 1175b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1176b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 1177b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1178b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1180b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1182ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org 1183ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org send_streams_[ssrc]->MuteStream(mute); 1184ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.org return true; 1185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1188b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1189587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " 1190587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 11913c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 11923c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1193d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 11943c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org recv_rtp_extensions_ = FilterRtpExtensions(extensions); 1195d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1196d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 1197d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 1198d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1199d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 1200d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1201b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1202b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1203b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1204b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1205b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1206587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " 1207587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 12083c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 12093c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 12103c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 12113c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org send_rtp_extensions_ = FilterRtpExtensions(extensions); 1212d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1213d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 1214d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 1215d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1216d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 1217d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1218b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1219b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1220b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1221b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetStartSendBandwidth(int bps) { 1222b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1223b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetStartSendBandwidth: " << bps; 1224b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1225b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1226b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1227b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int bps) { 1228b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1229b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetMaxSendBandwidth: " << bps; 1230b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1231b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1232b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1233b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 1234b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); 1235b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 12365301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 12375301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_streams_.begin(); 12385301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it != send_streams_.end(); 12395301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ++it) { 12405301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it->second->SetOptions(options_); 12415301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1242b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1243b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1244b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1245b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1246b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1247b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1248b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1249d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Socket::OPT_RCVBUF, 1250b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1251b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(sriniv): Remove or re-enable this. 1253b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // As part of b/8030474, send-buffer is size now controlled through 1254b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // portallocator flags. 1255b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // network_interface_->SetOption(NetworkInterface::ST_RTP, 1256d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org // rtc::Socket::OPT_SNDBUF, 1257b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // kVideoRtpBufferSize); 1258b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1259b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1260b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1261b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1262b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1263b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1264d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(rtc::Message* msg) { 1265b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1266b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1267b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1268b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { 1269d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1270b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendPacket(&packet); 1271b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1272b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1273b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1274d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Buffer packet(data, len, kMaxRtpPacketLen); 1275b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendRtcp(&packet); 1276b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1277b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1278b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1279b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1280b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1281b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1282b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1283b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1284b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1285b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1286b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1287b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1288b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1289b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1290b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1291b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1292b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1293b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1294b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1295b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 12966ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 12976ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 12986ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 12996ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 13005301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings) 13015301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org : config(config), options(options), codec_settings(codec_settings) { 13026ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org} 13036ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 1304b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 13065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory, 13076ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 13085301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings, 13095301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const StreamParams& sp, 13105301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) 1311b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : call_(call), 1312b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org encoder_factory_(encoder_factory), 1313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 1314b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org parameters_(webrtc::VideoSendStream::Config(), options, codec_settings), 1315b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org capturer_(NULL), 1316b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 13175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org muted_(false) { 13185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 13195301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13205301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 13215301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 13225301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 13235301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 13245301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 13255301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13265301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings params; 13275301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (codec_settings.Get(¶ms)) { 13285301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodec(params); 13295301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1332b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1333b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 13345301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 13355301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org call_->DestroyVideoSendStream(stream_); 13365301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 13376ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org delete parameters_.config.encoder_settings.encoder; 1338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void SetWebRtcFrameToBlack(webrtc::I420VideoFrame* video_frame) { 1341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(video_frame != NULL); 1342b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 1343b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 16, 1344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1345b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 1346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 1349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void CreateBlackFrame(webrtc::I420VideoFrame* video_frame, 1354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->CreateEmptyFrame( 1357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org width, height, width, (width + 1) / 2, (width + 1) / 2); 1358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetWebRtcFrameToBlack(video_frame); 1359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void ConvertToI420VideoFrame(const VideoFrame& frame, 1362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::I420VideoFrame* i420_frame) { 1363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org i420_frame->CreateFrame( 1364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch() * frame.GetHeight()), 1365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetYPlane(), 1366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch() * ((frame.GetHeight() + 1) / 2)), 1367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetUPlane(), 1368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch() * ((frame.GetHeight() + 1) / 2)), 1369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetVPlane(), 1370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetWidth()), 1371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetHeight()), 1372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch()), 1373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch()), 1374b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch())); 1375b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1379b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 1380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "InputFrame: " << frame->GetWidth() << "x" 1381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << frame->GetHeight(); 1382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock before copying, can be called concurrently when swapping input source. 1383d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope frame_cs(&frame_lock_); 1384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!muted_) { 1385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ConvertToI420VideoFrame(*frame, &video_frame_); 1386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1387c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org // Create a black frame to transmit instead. 1388c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org CreateBlackFrame(&video_frame_, 1389c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org static_cast<int>(frame->GetWidth()), 1390c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org static_cast<int>(frame->GetHeight())); 1391b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1392d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 13935301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ == NULL) { 13945301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_WARNING) << "Capturer inputting frames before send codecs are " 13955301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org "configured, dropping."; 13965301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org return; 13975301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1398b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 1399b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(format_.height == 0); 1400b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1403b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1404c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions( 1405c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org video_frame_.width(), video_frame_.height(), capturer->IsScreencast()); 1406c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SwapFrame: " << video_frame_.width() << "x" 1408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << video_frame_.height() << " -> (codec) " 1409bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org << parameters_.encoder_config.streams.back().width << "x" 1410bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org << parameters_.encoder_config.streams.back().height; 1411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Input()->SwapFrame(&video_frame_); 1412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1415b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1416b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1417b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1418b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1421d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14239359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (capturer == NULL) { 14249359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org if (stream_ != NULL) { 14259359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 14269359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org webrtc::I420VideoFrame black_frame; 14279359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org 14289359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int width = format_.width; 14299359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int height = format_.height; 14309359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org int half_width = (width + 1) / 2; 14319359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org black_frame.CreateEmptyFrame( 14329359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org width, height, width, half_width, half_width); 14339359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org SetWebRtcFrameToBlack(&black_frame); 1434c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions(width, height, false); 14359359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org stream_->Input()->SwapFrame(&black_frame); 14369359cb3e75c7100dab4c687f60dd28dc613280e4pbos@webrtc.org } 1437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1444b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1445b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1446b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1459d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1460b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1461b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1462b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 14636ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 1466bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.streams.back().max_framerate = 1467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1468c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org SetDimensions(format.width, format.height, false); 1469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1471b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1475ef8bb8d9b0bca0b1fd1ddb0a17df665e9dfaf9adpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1476d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1477b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1478b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1479b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1480b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1481d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (capturer_ == NULL) { 1483b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1484b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1485b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_->SignalVideoFrame.disconnect(this); 1486b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 14915301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 1492d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 14935301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings codec_settings; 14945301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (parameters_.codec_settings.Get(&codec_settings)) { 14955301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, options); 14965301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } else { 14975301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.options = options; 14985301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 14995301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 1500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 15015301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings) { 1502d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 15035301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 15045301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 15055301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 15065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings, 15075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 15086ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org std::vector<webrtc::VideoStream> video_streams = 15096ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org encoder_factory_->CreateVideoStreams( 15105301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec, options, parameters_.config.rtp.ssrcs.size()); 15116ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (video_streams.empty()) { 1512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1513b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1514bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.streams = video_streams; 15155301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 15165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec.height, 1517b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 1518b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 15196ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15206ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org webrtc::VideoEncoder* old_encoder = 15216ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config.encoder_settings.encoder; 15226ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config.encoder_settings.encoder = 15235301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org encoder_factory_->CreateVideoEncoder(codec_settings.codec, options); 15245301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 15255301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 15265301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 15275301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15285301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org // Set RTX payload type if RTX is enabled. 15295301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 15305301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 1531543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1532543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org options.use_payload_padding.Get( 1533543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org ¶meters_.config.rtp.rtx.pad_with_redundant_payloads); 15345301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15355301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15365301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (IsNackEnabled(codec_settings.codec)) { 15375301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.nack.rtp_history_ms = kNackHistoryMs; 15385301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15395301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15405ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org options.suspend_below_min_bitrate.Get( 15415ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org ¶meters_.config.suspend_below_min_bitrate); 15425ff71ab4b369fe3dbfaec5f91cd2e491397eff33pbos@webrtc.org 15435301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.codec_settings.Set(codec_settings); 15446ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 1545543e589205af006f6b999a2c5df51d3fb722d925pbos@webrtc.org 1546b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 1547b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete old_encoder; 1548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1550d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 1551d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 1552d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1553d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 1554d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1555d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1556d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1557c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( 1558c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int width, 1559c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org int height, 1560c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org bool override_max) { 1561bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org assert(!parameters_.encoder_config.streams.empty()); 1562b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height; 1563c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1564c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org VideoCodecSettings codec_settings; 1565c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 1566c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org // Restrict dimensions according to codec max. 1567c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org if (!override_max) { 1568c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org if (codec_settings.codec.width < width) 1569c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org width = codec_settings.codec.width; 1570c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org if (codec_settings.codec.height < height) 1571c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org height = codec_settings.codec.height; 1572c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org } 1573c4175b9fdf7d23eb58a044ff39e2b096f9091995pbos@webrtc.org 1574bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org if (parameters_.encoder_config.streams.back().width == width && 1575bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.streams.back().height == height) { 1576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1579bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org webrtc::VideoEncoderConfig encoder_config = parameters_.encoder_config; 1580bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = 1581bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_factory_->CreateVideoEncoderSettings(codec_settings.codec, 1582bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.options); 15836f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1584cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org VideoCodec codec = codec_settings.codec; 1585cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org codec.width = width; 1586cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org codec.height = height; 1587cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org 1588bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.streams = encoder_factory_->CreateVideoStreams( 1589bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org codec, parameters_.options, parameters_.config.rtp.ssrcs.size()); 15906f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1591bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); 1592bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 1593bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings( 1594bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org codec_settings.codec, 1595bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings); 1596bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 1597bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_config.encoder_specific_settings = NULL; 15986f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 15996f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (!stream_reconfigured) { 1600b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 1601b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 1602b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1604cddd17c0f89cfaa9d2f21118ae90b45dae3b4aeepbos@webrtc.org 1605bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config = encoder_config; 1606b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 1609d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 16105301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org assert(stream_ != NULL); 1611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 1613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 1616d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 16175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 16185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org stream_->Stop(); 16195301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 1621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1623e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoSenderInfo 1624e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 1625e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoSenderInfo info; 1626d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&lock_); 1627e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (size_t i = 0; i < parameters_.config.rtp.ssrcs.size(); ++i) { 1628e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(parameters_.config.rtp.ssrcs[i]); 1629e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1630e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1631c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org if (stream_ == NULL) { 1632c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org return info; 1633c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org } 1634c3d2bd28a3e8badc434a5081dd36f4ac41b4e3f2pbos@webrtc.org 1635e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 1636e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_input = stats.input_frame_rate; 1637e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 1638e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1639e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32_t, webrtc::StreamStats>::iterator it = 1640e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.substreams.begin(); 1641e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != stats.substreams.end(); 1642e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1643e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 1644e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::StreamStats stream_stats = it->second; 1645e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.bytes_sent += stream_stats.rtp_stats.bytes + 1646e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stream_stats.rtp_stats.header_bytes + 1647e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stream_stats.rtp_stats.padding_bytes; 1648e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_sent += stream_stats.rtp_stats.packets; 1649e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 1650e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1651e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1652e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (!stats.substreams.empty()) { 1653e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 1654e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::StreamStats first_stream_stats = stats.substreams.begin()->second; 1655e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.fraction_lost = 1656e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 1657e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org (1 << 8); 1658e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1659e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1660e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (capturer_ != NULL && !capturer_->IsMuted()) { 1661e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoFormat last_captured_frame_format; 1662e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, 1663e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &info.effects_frame_drops, 1664e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &info.capturer_frame_time, 1665e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &last_captured_frame_format); 1666e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 1667e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 1668e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.send_frame_width = 1669bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org static_cast<int>(parameters_.encoder_config.streams.front().width); 1670e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.send_frame_height = 1671bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org static_cast<int>(parameters_.encoder_config.streams.front().height); 1672e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1673e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1674e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Support or remove the following stats. 1675e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_cached = -1; 1676e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.rtt_ms = -1; 1677e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1678e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 1679e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1680e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 1682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 1683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 1684b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 16856ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 16866f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 16876f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 1688bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = 1689bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_factory_->CreateVideoEncoderSettings(codec_settings.codec, 1690bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.options); 1691bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org 1692bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org stream_ = call_->CreateVideoSendStream(parameters_.config, 1693bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config); 16946f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1695bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings( 1696bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org codec_settings.codec, 1697bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings); 16986f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1699bbe0a8517d7f9da7aa779bff77cdbb70df358437pbos@webrtc.org parameters_.encoder_config.encoder_specific_settings = NULL; 17006f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 1702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1704b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1706d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 1707d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::Call* call, 1708d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::VideoReceiveStream::Config& config, 1709d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) 1710d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org : call_(call), 1711d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_(NULL), 1712b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org config_(config), 1713b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org renderer_(NULL), 1714d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_(-1), 1715b648b9d85c5d07b0866ef45f5be587f71b0849b4pbos@webrtc.org last_height_(-1) { 1716d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.renderer = this; 1717d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 1718d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRecvCodecs(recv_codecs); 1719d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1720d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1721d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 1722d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1723d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1724d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1725d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 1726d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 1727d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 1728d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Base receive codecs off recv_codecs_ and set up using a 1729d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // DecoderFactory similar to send side. Pending webrtc:2854. 1730d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // Also set up default codecs if there's nothing in recv_codecs_. 1731d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoCodec codec; 1732d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org memset(&codec, 0, sizeof(codec)); 1733d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1734d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.plType = kDefaultVideoCodecPref.payload_type; 1735d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org strcpy(codec.plName, kDefaultVideoCodecPref.name); 1736d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecType = webrtc::kVideoCodecVP8; 1737d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.resilience = webrtc::kResilientStream; 1738d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.numberOfTemporalLayers = 1; 1739d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.denoisingOn = true; 1740d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.errorConcealmentOn = false; 1741d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.automaticResizeOn = false; 1742d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.frameDroppingOn = true; 1743d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.keyFrameInterval = 3000; 1744d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // Bitrates don't matter and are ignored for the receiver. This is put in to 1745d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // have the current underlying implementation accept the VideoCodec. 1746d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.minBitrate = codec.startBitrate = codec.maxBitrate = 300; 1747d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.codecs.clear(); 1748d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.codecs.push_back(codec); 1749d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1750d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 1751d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1752257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.nack.rtp_history_ms = 1753257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org IsNackEnabled(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 1754257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org config_.rtp.remb = IsRembEnabled(recv_codecs.begin()->codec); 1755257e130a1639febeb3ffc4d42943be3cb58151c7pbos@webrtc.org 1756d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1757d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1758d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1759d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 1760d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 1761d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.extensions = extensions; 1762d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1763d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1764d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1765d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 1766d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (stream_ != NULL) { 1767d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1768d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1769d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 1770d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_->Start(); 1771d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1772d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1773d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 1774d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::I420VideoFrame& frame, 1775d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int time_to_render_ms) { 1776d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1777d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ == NULL) { 1778d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 1779d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return; 1780d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1781d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1782d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 1783d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(frame.width(), frame.height()); 1784d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1785d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1786d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_VERBOSE) << "RenderFrame: (" << frame.width() << "x" << frame.height() 1787d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org << ")"; 1788d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1789d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const WebRtcVideoRenderFrame render_frame(&frame); 1790d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_->RenderFrame(&render_frame); 1791d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1792d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1793d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 1794d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org cricket::VideoRenderer* renderer) { 1795d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1796d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_ = renderer; 1797d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 1798d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(last_width_, last_height_); 1799d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1800d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1801d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1802d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 1803d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 1804d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // design. 1805d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1806d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return renderer_; 1807d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1808d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1809d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 1810d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int height) { 1811d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope crit(&renderer_lock_); 1812d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 1813d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 1814d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1815d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_ = width; 1816d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_ = height; 1817d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1818d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1819e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoReceiverInfo 1820e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 1821e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoReceiverInfo info; 1822e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 1823e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 1824e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.bytes_rcvd = stats.rtp_stats.bytes + stats.rtp_stats.header_bytes + 1825e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.rtp_stats.padding_bytes; 1826e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_rcvd = stats.rtp_stats.packets; 1827e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1828e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 1829e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 1830e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_output = stats.render_frame_rate; 1831e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1832d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope frame_cs(&renderer_lock_); 1833e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.frame_width = last_width_; 1834e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.frame_height = last_height_; 1835e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1836e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Support or remove the following stats. 1837e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_concealed = -1; 1838e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1839e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 1840e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1841e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 1843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 1844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 1846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 1847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!codecs.empty()); 1848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 1850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 1851e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 1852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, int> rtx_mapping; // video payload type -> rtx payload type. 1853b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 1855b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1856b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 1857b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 1858b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 1859b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1860b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 1861b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 1862b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 1863b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1864b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 1866e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 1867b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1868b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 1869b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 1870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 1871b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.red_payload_type == -1); 1872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 1873b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1874b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1875b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1876b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 1877b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 1878b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.ulpfec_payload_type == -1); 1879b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 1880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 1884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 1885b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 1886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org &associated_payload_type)) { 1887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RTX codec without associated payload type: " 1888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 1889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 1892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 1896b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 1897b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1898b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 1900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 1901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 1904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 1905b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!video_codecs.empty()); 1906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1907e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 1908e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org it != rtx_mapping.end(); 1909e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org ++it) { 1910e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!payload_used[it->first]) { 1911e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 1912e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1913e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1914e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO) { 1915e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX not mapped to regular video codec."; 1916e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1917e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1918e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1919e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 1920b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Write tests that figure out that I have not verified that RTX 1921b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // codecs aren't mapped to bogus payloads. 1922b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 1923b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 1924b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtx_mapping[video_codecs[i].codec.id] != 0) { 1925b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 1926b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1927b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1928b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1929b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 1930b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1931b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1932b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 1933b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 1934b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) { 1935b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 1936b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 1937b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (encoder_factory_->SupportsCodec(mapped_codecs[i].codec)) { 1938b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org supported_codecs.push_back(mapped_codecs[i]); 1939b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1940b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1941b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return supported_codecs; 1942b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1943b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1944b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 1945b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1946b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 1947