webrtcvideoengine2.cc revision 6f48f1bf68a10669c9bcd81262c1a98ed2a8d462
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/base/buffer.h" 36b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/base/logging.h" 37b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/base/stringutils.h" 38b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videocapturer.h" 39b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videorenderer.h" 40df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org#include "talk/media/webrtc/constants.h" 41b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideocapturer.h" 42b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoframe.h" 43b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvoiceengine.h" 44b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/call.h" 45b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// TODO(pbos): Move codecs out of modules (webrtc:3070). 46b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" 47b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 48b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#define UNIMPLEMENTED \ 49b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Call to unimplemented function " << __FUNCTION__; \ 50b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(false) 51b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 52b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace cricket { 53b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 54b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 55b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// duration hasn't been implemented. 56b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 57b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 58b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 59b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 60b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstruct VideoCodecPref { 61b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type; 62b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const char* name; 63b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rtx_payload_type; 64df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org} kDefaultVideoCodecPref = {100, kVp8CodecName, 96}; 65b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 66b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoCodecPref kRedPref = {116, kRedCodecName, -1}; 67b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoCodecPref kUlpfecPref = {117, kUlpfecCodecName, -1}; 68b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 69b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// The formats are sorted by the descending order of width. We use the order to 70b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// find the next format for CPU and bandwidth adaptation. 718fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.orgconst VideoFormatPod kDefaultMaxVideoFormat = { 72b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 640, 400, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}; 73b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 74b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 75b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& requested_codec, 76b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* matching_codec) { 77b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 78b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 79b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *matching_codec = codecs[i]; 80b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 81b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 82b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 83b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 84b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 85b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 86f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.orgstatic void AddDefaultFeedbackParams(VideoCodec* codec) { 87f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kFir(kRtcpFbParamCcm, kRtcpFbCcmParamFir); 88f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kFir); 89f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kNack(kRtcpFbParamNack, kParamValueEmpty); 90f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kNack); 91f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kPli(kRtcpFbParamNack, kRtcpFbNackParamPli); 92f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kPli); 93f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org const FeedbackParam kRemb(kRtcpFbParamRemb, kParamValueEmpty); 94f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org codec->AddFeedbackParam(kRemb); 95f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org} 96f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org 97f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.orgstatic bool IsNackEnabled(const VideoCodec& codec) { 98f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org return codec.HasFeedbackParam( 99f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); 100f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org} 101f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org 102b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultVideoCodec() { 103b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec default_codec(kDefaultVideoCodecPref.payload_type, 104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.name, 1058fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org kDefaultMaxVideoFormat.width, 1068fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org kDefaultMaxVideoFormat.height, 107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultFramerate, 108b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 0); 109f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org AddDefaultFeedbackParams(&default_codec); 110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return default_codec; 111b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultRedCodec() { 114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kRedPref.payload_type, kRedPref.name, 0, 0, 0, 0); 115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultUlpfecCodec() { 118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kUlpfecPref.payload_type, kUlpfecPref.name, 0, 0, 0, 0); 119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic std::vector<VideoCodec> DefaultVideoCodecs() { 122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodec> codecs; 123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultVideoCodec()); 124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultRedCodec()); 125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultUlpfecCodec()); 126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (kDefaultVideoCodecPref.rtx_payload_type != -1) { 127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back( 128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec::CreateRtxCodec(kDefaultVideoCodecPref.rtx_payload_type, 129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.payload_type)); 130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return codecs; 132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1343c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic bool ValidateRtpHeaderExtensionIds( 1353c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1363c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::set<int> extensions_used; 1373c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1383c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (extensions[i].id < 0 || extensions[i].id >= 15 || 1393c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org !extensions_used.insert(extensions[i].id).second) { 1403c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_ERROR) << "RTP extensions are with incorrect or duplicate ids."; 1413c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1423c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1433c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1443c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return true; 1453c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 1463c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1473c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.orgstatic std::vector<webrtc::RtpExtension> FilterRtpExtensions( 1483c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1493c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org std::vector<webrtc::RtpExtension> webrtc_extensions; 1503c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 1513c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org // Unsupported extensions will be ignored. 1523c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (webrtc::RtpExtension::IsSupported(extensions[i].uri)) { 1533c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org webrtc_extensions.push_back(webrtc::RtpExtension( 1543c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org extensions[i].uri, extensions[i].id)); 1553c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } else { 1563c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org LOG(LS_WARNING) << "Unsupported RTP extension: " << extensions[i].uri; 1573c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1583c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org } 1593c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return webrtc_extensions; 1603c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org} 1613c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 1620d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.orgWebRtcVideoEncoderFactory2::~WebRtcVideoEncoderFactory2() { 1630d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org} 1640d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org 165d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgstd::vector<webrtc::VideoStream> WebRtcVideoEncoderFactory2::CreateVideoStreams( 166d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 167d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 168d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 169d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org assert(SupportsCodec(codec)); 170d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org if (num_streams != 1) { 171d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org LOG(LS_ERROR) << "Unsupported number of streams: " << num_streams; 172d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return std::vector<webrtc::VideoStream>(); 1736ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org } 174b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 175d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 176d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 177d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 178d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 179d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultFramerate; 180d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 181d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int min_bitrate = kMinVideoBitrate; 182d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMinBitrate, &min_bitrate); 183d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int max_bitrate = kMaxVideoBitrate; 184d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxBitrate, &max_bitrate); 185d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.min_bitrate_bps = min_bitrate * 1000; 186d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate * 1000; 187d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 188d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int max_qp = 56; 189d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 190d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 191d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 192d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 193d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 194d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 195b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 196d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgwebrtc::VideoEncoder* WebRtcVideoEncoderFactory2::CreateVideoEncoder( 197d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 198d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options) { 199d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org assert(SupportsCodec(codec)); 2006f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2016f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return webrtc::VP8Encoder::Create(); 2026f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2036f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org // This shouldn't happen, we should be able to create encoders for all codecs 2046f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org // we support. 2056f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(false); 2066f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 2076f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 2086f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2096f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid* WebRtcVideoEncoderFactory2::CreateVideoEncoderSettings( 2106f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 2116f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoOptions& options) { 2126f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(SupportsCodec(codec)); 2136f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2146f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org webrtc::VideoCodecVP8* settings = new webrtc::VideoCodecVP8(); 2156f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->resilience = webrtc::kResilientStream; 2166f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->numberOfTemporalLayers = 1; 2176f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org options.video_noise_reduction.Get(&settings->denoisingOn); 2186f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->errorConcealmentOn = false; 2196f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->automaticResizeOn = false; 2206f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->frameDroppingOn = true; 2216f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org settings->keyFrameInterval = 3000; 2226f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return settings; 2236f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2246f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return NULL; 2256f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 2266f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2276f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoEncoderFactory2::DestroyVideoEncoderSettings( 2286f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org const VideoCodec& codec, 2296f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org void* encoder_settings) { 2306f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(SupportsCodec(codec)); 2316f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (encoder_settings == NULL) { 2326f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return; 2336f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2346f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 2356f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (_stricmp(codec.name.c_str(), kVp8CodecName) == 0) { 2366f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org delete reinterpret_cast<webrtc::VideoCodecVP8*>(encoder_settings); 2376f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org return; 2386f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org } 2396f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org // We should be able to destroy all encoder settings we've allocated. 2406f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org assert(false); 241d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 242d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 243d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgbool WebRtcVideoEncoderFactory2::SupportsCodec(const VideoCodec& codec) { 244df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org return _stricmp(codec.name.c_str(), kVp8CodecName) == 0; 245d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 246b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 247b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2() { 248b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Construct without a factory or voice engine. 249b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(NULL, NULL, new talk_base::CpuMonitor(NULL)); 250b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 251b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2( 253b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoChannelFactory* channel_factory) { 254b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Construct without a voice engine. 255b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(channel_factory, NULL, new talk_base::CpuMonitor(NULL)); 256b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 257b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 258b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::Construct(WebRtcVideoChannelFactory* channel_factory, 259b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVoiceEngine* voice_engine, 260b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CpuMonitor* cpu_monitor) { 261b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2"; 262b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org worker_thread_ = NULL; 263b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org voice_engine_ = voice_engine; 264b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = false; 265b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capture_started_ = false; 266b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_.reset(cpu_monitor); 267b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org channel_factory_ = channel_factory; 268b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 269b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs_ = DefaultVideoCodecs(); 2708fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org default_codec_format_ = VideoFormat(kDefaultMaxVideoFormat); 271587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org 272587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 273587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, 274587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpTimestampOffsetHeaderExtensionDefaultId)); 275587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org rtp_header_extensions_.push_back( 276587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 277587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 278b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 279b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 280b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 281b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 282b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 283b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 284b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Terminate(); 285b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 286b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 287b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 288b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::Init(talk_base::Thread* worker_thread) { 289b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 290b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org worker_thread_ = worker_thread; 291b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(worker_thread_ != NULL); 292b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 293b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->set_thread(worker_thread_); 294b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!cpu_monitor_->Start(kCpuMonitorPeriodMs)) { 295b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Failed to start CPU monitor."; 296b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_.reset(); 297b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 298b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 299b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 300b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 301b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 302b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 303b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::Terminate() { 304b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Terminate"; 305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->Stop(); 307b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 308b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = false; 309b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 311b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgint WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } 312b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetOptions(const VideoOptions& options) { 314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Do we need this? This is a no-op in the existing 315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // WebRtcVideoEngine implementation. 316b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); 317b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // options_ = options; 318b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoEncoderConfig& config) { 3238fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org const VideoCodec& codec = config.max_codec; 3248fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org // TODO(pbos): Make use of external encoder factory. 3258fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (!GetVideoEncoderFactory()->SupportsCodec(codec)) { 3268fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported:" 3278fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org << codec.ToString(); 3288fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return false; 3298fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 3308fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 3318fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org default_codec_format_ = 3328fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoFormat(codec.width, 3338fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org codec.height, 3348fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoFormat::FpsToInterval(codec.framerate), 3358fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org FOURCC_ANY); 3368fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org video_codecs_.clear(); 3378fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org video_codecs_.push_back(codec); 338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoEncoderConfig WebRtcVideoEngine2::GetDefaultEncoderConfig() const { 342b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoEncoderConfig(DefaultVideoCodec()); 343b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 345b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel) { 347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "CreateChannel: " 348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (voice_channel != NULL ? "With" : "Without") 349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << " voice channel."; 350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoChannel2* channel = 351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org channel_factory_ != NULL 352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ? channel_factory_->Create(this, voice_channel) 353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : new WebRtcVideoChannel2( 3540d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org this, voice_channel, GetVideoEncoderFactory()); 355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!channel->Init()) { 356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete channel; 357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 359e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org channel->SetRecvCodecs(video_codecs_); 360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return channel; 361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return rtp_header_extensions_; 370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { 373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Set up logging. 374b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; 375b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if min_sev == -1, we keep the current log level. 376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (min_sev < 0) { 377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(min_sev == -1); 378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 379b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 387b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetLocalRenderer(VideoRenderer* renderer) { 388b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement or remove. Unclear which stream should be rendered 389b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // locally even. 390b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 391b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 392b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 395b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 3988fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 3998fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 4008fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (codec.Matches(in)) { 4018fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 403b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 404b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 405b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 406b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 409b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// dimensions will be used for aspect ratio matching. 411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& current, 413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* out) { 414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(out != NULL); 415b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 416b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width != requested.height && 417b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 418b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // 0xn and nx0 are invalid resolutions. 419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec matching_codec; 423b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 424b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Codec not supported. 425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->id = requested.id; 429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->name = requested.name; 430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->preference = requested.preference; 431b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->framerate = 433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::_min(requested.framerate, matching_codec.framerate); 434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->feedback_params = requested.feedback_params; 4368fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width = requested.width; 4378fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height = requested.height; 4388fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 4398fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return true; 4408fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 4418fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 4428fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org while (out->width > matching_codec.width) { 4438fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->width /= 2; 4448fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org out->height /= 2; 4458fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org } 4468fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org 4478fdeee6abfcb560233b5e769afb1c1c72cc2100dpbos@webrtc.org return out->width > 0 && out->height > 0; 448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetVoiceEngine(WebRtcVoiceEngine* voice_engine) { 451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "SetVoiceEngine can not be called after Init"; 453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org voice_engine_ = voice_engine; 456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 460b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 461b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 462b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 466b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 471d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgWebRtcVideoEncoderFactory2* WebRtcVideoEngine2::GetVideoEncoderFactory() { 472d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return &default_video_encoder_factory_; 473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 4756ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org// Thin map between VideoFrame and an existing webrtc::I420VideoFrame 476b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// to avoid having to copy the rendered VideoFrame prematurely. 477b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This implementation is only safe to use in a const context and should never 478b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be written to. 4796ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgclass WebRtcVideoRenderFrame : public VideoFrame { 480b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org public: 481b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org explicit WebRtcVideoRenderFrame(const webrtc::I420VideoFrame* frame) 482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : frame_(frame) {} 483b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 484b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool InitToBlack(int w, 485b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 486b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) OVERRIDE { 490b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 491b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool Reset(uint32 fourcc, 495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int w, 496b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dw, 498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dh, 499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* sample, 500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t sample_size, 501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 503b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 504b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp, 505b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rotation) OVERRIDE { 506b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 507b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 508b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 509b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 510b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetWidth() const OVERRIDE { 511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->width()); 512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 513b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetHeight() const OVERRIDE { 514b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->height()); 515b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 516b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 517b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetYPlane() const OVERRIDE { 518b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kYPlane); 519b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetUPlane() const OVERRIDE { 521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kUPlane); 522b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 523b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetVPlane() const OVERRIDE { 524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kVPlane); 525b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetYPlane() OVERRIDE { 528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 529b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 530b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetUPlane() OVERRIDE { 532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetVPlane() OVERRIDE { 536b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 537b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 539b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 540b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetYPitch() const OVERRIDE { 541b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kYPlane); 542b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 543b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetUPitch() const OVERRIDE { 544b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kUPlane); 545b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 546b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetVPitch() const OVERRIDE { 547b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kVPlane); 548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void* GetNativeHandle() const OVERRIDE { return NULL; } 551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelWidth() const OVERRIDE { return 1; } 553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelHeight() const OVERRIDE { return 1; } 554b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetElapsedTime() const OVERRIDE { 556b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert millisecond render time to ns timestamp. 557b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->render_time_ms() * talk_base::kNumNanosecsPerMillisec; 558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetTimeStamp() const OVERRIDE { 560b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert 90K rtp timestamp to ns timestamp. 561b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return (frame_->timestamp() / 90) * talk_base::kNumNanosecsPerMillisec; 562b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 563b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetElapsedTime(int64 elapsed_time) OVERRIDE { UNIMPLEMENTED; } 564b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetTimeStamp(int64 time_stamp) OVERRIDE { UNIMPLEMENTED; } 565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 566b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int GetRotation() const OVERRIDE { 567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return ROTATION_0; 569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* Copy() const OVERRIDE { 572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool MakeExclusive() OVERRIDE { 577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 581b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t CopyToBuffer(uint8* buffer, size_t size) const { 582b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 583b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; 584b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 585b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 586b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(fbarchard): Refactor into base class and share with LMI 587b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, 588b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* buffer, 589b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t size, 590b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int stride_rgb) const OVERRIDE { 591b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t width = GetWidth(); 592b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t height = GetHeight(); 593b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t needed = (stride_rgb >= 0 ? stride_rgb : -stride_rgb) * height; 594b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (size < needed) { 595b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "RGB buffer is not large enough"; 596b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 599b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (libyuv::ConvertFromI420(GetYPlane(), 600b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetYPitch(), 601b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPlane(), 602b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPitch(), 603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPlane(), 604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPitch(), 605b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org buffer, 606b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stride_rgb, 607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(width), 608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(height), 609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org to_fourcc)) { 610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RGB type not supported: " << to_fourcc; 611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; // 0 indicates error 612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org protected: 617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* CreateEmptyFrame(int w, 618b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) const OVERRIDE { 623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Remove WebRtcVideoFrame dependency, and have a non-const 624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // version of I420VideoFrame wrapped. 625b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoFrame* frame = new WebRtcVideoFrame(); 626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame->InitToBlack( 627b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org w, h, pixel_width, pixel_height, elapsed_time, time_stamp); 628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame; 629b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org private: 632b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const webrtc::I420VideoFrame* const frame_; 633b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org}; 634b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 635b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 636b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine, 637b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel, 638b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 639b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : encoder_factory_(encoder_factory) { 640b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Connect the video and audio with |voice_channel|. 641b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call::Config config(this); 642b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(webrtc::Call::Create(config), engine); 643b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 645b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine, 648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : encoder_factory_(encoder_factory) { 650b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(call, engine); 651b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 653b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::Construct(webrtc::Call* call, 654b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine) { 655b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 656b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 657b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_.reset(call); 658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_renderer_ = NULL; 659b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_recv_ssrc_ = 0; 6616f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 6626f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org SetDefaultOptions(); 6636f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org} 6646f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 6656f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.orgvoid WebRtcVideoChannel2::SetDefaultOptions() { 6666f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org options_.video_noise_reduction.Set(true); 667b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 668b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 669b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 671b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 672b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 673b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 674b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 675b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 677d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.begin(); 679b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != receive_streams_.end(); 680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 684b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 685b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::Init() { return true; } 686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace { 688b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { 690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::stringstream out; 691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << '{'; 692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 693b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << codecs[i].ToString(); 694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (i != codecs.size() - 1) { 695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << ", "; 696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << '}'; 699b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return out.str(); 700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 702e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.orgstatic bool ValidateCodecFormats(const std::vector<VideoCodec>& codecs) { 703e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org bool has_video = false; 704e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 705e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!codecs[i].ValidateCodecFormat()) { 706e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return false; 707e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 708e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (codecs[i].GetCodecType() == VideoCodec::CODEC_VIDEO) { 709e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org has_video = true; 710e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 711e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 712e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!has_video) { 713e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "Setting codecs without a video codec is invalid: " 714e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org << CodecVectorToString(codecs); 715e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return false; 716e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 717e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return true; 718e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org} 719e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 720587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.orgstatic std::string RtpExtensionsToString( 721587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 722587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org std::stringstream out; 723587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << '{'; 724587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 725587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << "{" << extensions[i].uri << ": " << extensions[i].id << "}"; 726587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org if (i != extensions.size() - 1) { 727587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << ", "; 728587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org } 729587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org } 730587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org out << '}'; 731587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org return out.str(); 732587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org} 733587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org 734b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace 735b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 736b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 737b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Must these receive codecs propagate to existing receive 738b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // streams? 739b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 740b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 741b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 742b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 743b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 744b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 745b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 746b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without video codec payloads."; 747b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 748b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 749b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 750b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Add a decoder factory which controls supported codecs. 751b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Blocked on webrtc:2854. 752b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 753df9bbbee56f4d9ecef93b3c46964b6f29803f81bbuildbot@webrtc.org if (_stricmp(mapped_codecs[i].codec.name.c_str(), kVp8CodecName) != 0) { 754b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported codec: '" 755b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << mapped_codecs[i].codec.name << "'"; 756b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 757b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 758b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 759b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 760b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org recv_codecs_ = mapped_codecs; 761d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 762d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 763d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 764d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 765d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 766d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRecvCodecs(recv_codecs_); 767d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 768d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 769b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 770b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 771b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 772b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 773b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 775b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 776b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 777b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 778b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 779b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 780b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 781b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 782b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No video codecs supported by encoder factory."; 783b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 784b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 785b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 786b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_codec_.Set(supported_codecs.front()); 787b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 788b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 789d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 790d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 791d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 792d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 793d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org assert(it->second != NULL); 794d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetCodec(supported_codecs.front()); 795d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 796b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 797b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 798b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 799b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 800b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 801b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodecSettings codec_settings; 802b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 805b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 806b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *codec = codec_settings.codec; 807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, 811b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 812b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 813b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 814b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 815b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRender(bool render) { 821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. 822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); 823b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 827b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send && !send_codec_.IsSet()) { 829b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 830b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 831b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 832b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 833b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 834b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 835b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 836b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 837b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 838b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 839b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 840b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 841b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sp.ssrcs.empty()) { 844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No SSRCs in stream parameters."; 845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Make sure none of sp.ssrcs are used, not just the identifying 851b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ssrc. 852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) != send_streams_.end()) { 853b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Send stream with ssrc '" << ssrc << "' already exists."; 854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 855b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 856b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 8575301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> primary_ssrcs; 8585301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(&primary_ssrcs); 8595301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org std::vector<uint32> rtx_ssrcs; 8605301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(primary_ssrcs, &rtx_ssrcs); 8615301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 8625301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_ERROR) 8635301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 8645301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org << sp.ToString(); 865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 866b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 867b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 868b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoSendStream* stream = 8696ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org new WebRtcVideoSendStream(call_.get(), 8705301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org encoder_factory_, 8716ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options_, 8725301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_codec_, 8735301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp, 8745301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_rtp_extensions_); 8755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 876b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 877b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 878b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 879b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 885b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { 892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 896b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 897b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 898b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<uint32, WebRtcVideoSendStream*>::iterator it = 905b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.find(ssrc); 906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (it == send_streams_.end()) { 907b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 908b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 909b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 910b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 911b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.erase(it); 912b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 913b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 914b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 915b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 916b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 917b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 918b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 919b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 920b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 921b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); 922b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(sp.ssrcs.size() > 0); 923b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 924b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 925b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); // TODO(pbos): Is this ever valid? 926b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_recv_ssrc_ == 0) { 927b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_recv_ssrc_ = ssrc; 928b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 929b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 930b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Check if any of the SSRCs overlap. 931b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (receive_streams_.find(ssrc) != receive_streams_.end()) { 932b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Receive stream for SSRC " << ssrc << "already exists."; 933b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 934b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 935b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 936bd249bc711b3c9efd142eb8de3df489282fe693epbos@webrtc.org webrtc::VideoReceiveStream::Config config; 937d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ConfigureReceiverRtp(&config, sp); 938d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_[ssrc] = 939d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org new WebRtcVideoReceiveStream(call_.get(), config, recv_codecs_); 940d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 941d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 942d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 943d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 944d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::ConfigureReceiverRtp( 945d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoReceiveStream::Config* config, 946d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const StreamParams& sp) const { 947d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 948d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 949d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remote_ssrc = ssrc; 950d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 951b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 952f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org if (IsNackEnabled(recv_codecs_.begin()->codec)) { 953d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.nack.rtp_history_ms = kNackHistoryMs; 954f99c2f2dbcaab24b45295cb9e06c3c52ad349d81pbos@webrtc.org } 955d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.remb = true; 956d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.extensions = recv_rtp_extensions_; 957b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 958b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 959b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 960b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 961d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { 962d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 963d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 964b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 965d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 966b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 967b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 968b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 969d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 970d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (recv_codecs_[i].codec.id == kDefaultVideoCodecPref.payload_type) { 971d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.fec = recv_codecs_[i].fec; 972d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org uint32 rtx_ssrc; 973d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && 974d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 975d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].ssrc = rtx_ssrc; 976d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config->rtp.rtx[kDefaultVideoCodecPref.payload_type].payload_type = 977d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org recv_codecs_[i].rtx_payload_type; 978b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 979d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org break; 980b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 981b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 982b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 983b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 984b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 985b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { 986b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 987b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 988b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_recv_ssrc_; 989b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 990b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 991d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator stream = 992b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 993b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 994b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 995b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 996b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 997d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org delete stream->second; 998b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 999b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1000b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_recv_ssrc_) { 1001b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_recv_ssrc_ = 0; 1002b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1003b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1004b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1005b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1006b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1007b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 1008b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 1009b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 1010b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1011d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (default_recv_ssrc_!= 0) { 1012d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_[default_recv_ssrc_]->SetRenderer(renderer); 1013d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1014b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_recv_ssrc_; 1015b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_renderer_ = renderer; 1016d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return true; 1017b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1018b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1019d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1020d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1021d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1022d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return false; 1023b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1024b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1025b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1026b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1027b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1028b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1029b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { 1030b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1031b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_renderer_ == NULL) { 1032b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1033b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1034b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = default_renderer_; 1035b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1036b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1037b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1038d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1039d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.find(ssrc); 1040d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (it == receive_streams_.end()) { 1041b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1042b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1043b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1044b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1045b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1046b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1047b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(const StatsOptions& options, 1048b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoMediaInfo* info) { 1049e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info->Clear(); 1050e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillSenderStats(info); 1051e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillReceiverStats(info); 1052e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org FillBandwidthEstimationStats(info); 1053b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1054b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1055b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1056e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillSenderStats(VideoMediaInfo* video_media_info) { 1057e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1058e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org send_streams_.begin(); 1059e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != send_streams_.end(); 1060e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1061e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->senders.push_back(it->second->GetVideoSenderInfo()); 1062e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1063e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1064e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1065e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillReceiverStats(VideoMediaInfo* video_media_info) { 1066e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1067e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org receive_streams_.begin(); 1068e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != receive_streams_.end(); 1069e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1070e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org video_media_info->receivers.push_back(it->second->GetVideoReceiverInfo()); 1071e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1072e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1073e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1074e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgvoid WebRtcVideoChannel2::FillBandwidthEstimationStats( 1075e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoMediaInfo* video_media_info) { 1076e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Implement. 1077e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1078e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1079b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 1080b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1081b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 1082b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1083b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1084b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1085b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1086b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1087b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetCapturer(capturer); 1088b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1089b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1090b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1091b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1092b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1093b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1094b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1095b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1096b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1097b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1098b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1099b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1100b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1101b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1102b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1103b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::Buffer* packet, 1104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const talk_base::PacketTime& packet_time) { 11054e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 11064e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org call_->Receiver()->DeliverPacket( 11074e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()); 11084e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 11094e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 11104e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11114e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 11124e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11134e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 11144e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = 0; 1118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 11194e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 1120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!GetRtpSsrc(packet->data(), packet->length(), &ssrc)) { 1124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StreamParams sp; 1128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sp.ssrcs.push_back(ssrc); 1129c34bb3a88627672d99b1c037d36dbeb23407fae4pbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 1130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org AddRecvStream(sp); 1131d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRenderer(0, default_renderer_); 1132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 11331e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 11341e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 11351e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 11361e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet after creating default " 11371e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org "receiver."; 1138b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1139b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1140b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1141b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1142b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1143b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::Buffer* packet, 1144b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const talk_base::PacketTime& packet_time) { 11451e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 11461e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 11471e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1148b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTCP packet."; 1149b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1150b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1151b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1152b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 1153b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "OnReadySend: " << (ready ? "Ready." : "Not ready."); 1154b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1155b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1156b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { 1157b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1158b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 1159b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1160b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1161b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1162b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->MuteStream(mute); 1165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1167b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1168b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1169587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetRecvRtpHeaderExtensions: " 1170587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 11713c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 11723c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 1173d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 11743c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org recv_rtp_extensions_ = FilterRtpExtensions(extensions); 1175d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoReceiveStream*>::iterator it = 1176d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org receive_streams_.begin(); 1177d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != receive_streams_.end(); 1178d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1179d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(recv_rtp_extensions_); 1180d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1182b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1183b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1184b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1186587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org LOG(LS_INFO) << "SetSendRtpHeaderExtensions: " 1187587ef60056ff0e301a95a9eb8231fb0cae6b69b1pbos@webrtc.org << RtpExtensionsToString(extensions); 11883c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org if (!ValidateRtpHeaderExtensionIds(extensions)) 11893c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org return false; 11903c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org 11913c10758b3bb9519d5e582c00f454ac30196ac4e7pbos@webrtc.org send_rtp_extensions_ = FilterRtpExtensions(extensions); 1192d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1193d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org send_streams_.begin(); 1194d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it != send_streams_.end(); 1195d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org ++it) { 1196d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org it->second->SetRtpExtensions(send_rtp_extensions_); 1197d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1198b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1199b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1200b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1201b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetStartSendBandwidth(int bps) { 1202b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1203b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetStartSendBandwidth: " << bps; 1204b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1205b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1206b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1207b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int bps) { 1208b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1209b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetMaxSendBandwidth: " << bps; 1210b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1211b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1212b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1213b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 1214b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); 1215b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 12165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 12175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org send_streams_.begin(); 12185301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it != send_streams_.end(); 12195301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ++it) { 12205301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org it->second->SetOptions(options_); 12215301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1222b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1223b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1224b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1225b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1226b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1227b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1228b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1229b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::Socket::OPT_RCVBUF, 1230b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1231b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1232b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(sriniv): Remove or re-enable this. 1233b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // As part of b/8030474, send-buffer is size now controlled through 1234b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // portallocator flags. 1235b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // network_interface_->SetOption(NetworkInterface::ST_RTP, 1236b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // talk_base::Socket::OPT_SNDBUF, 1237b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // kVideoRtpBufferSize); 1238b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1239b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1240b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1241b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1242b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1243b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1244b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(talk_base::Message* msg) { 1245b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1246b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1247b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1248b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { 1249b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::Buffer packet(data, len, kMaxRtpPacketLen); 1250b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendPacket(&packet); 1251b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1253b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1254b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::Buffer packet(data, len, kMaxRtpPacketLen); 1255b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendRtcp(&packet); 1256b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1257b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1258b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1259b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1260b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1261b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1262b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1263b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1264b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1265b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1266b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1267b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1268b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1269b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1270b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1271b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1272b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1273b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1274b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1275b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 12766ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 12776ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 12786ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 12796ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 12805301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings) 12815301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org : config(config), options(options), codec_settings(codec_settings) { 12826ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org} 12836ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 1284b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1285b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 12865301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory, 12876ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 12885301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const Settable<VideoCodecSettings>& codec_settings, 12895301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const StreamParams& sp, 12905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) 1291b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : call_(call), 12925301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_(webrtc::VideoSendStream::Config(), options, codec_settings), 1293b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org encoder_factory_(encoder_factory), 1294b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_(NULL), 1295b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 1296b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 12975301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org muted_(false) { 12985301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.max_packet_size = kVideoMtu; 12995301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13005301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); 13015301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 13025301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org ¶meters_.config.rtp.rtx.ssrcs); 13035301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.c_name = sp.cname; 13045301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 13055301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 13065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings params; 13075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (codec_settings.Get(¶ms)) { 13085301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodec(params); 13095301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1311b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1312b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 13145301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 13155301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org call_->DestroyVideoSendStream(stream_); 13165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 13176ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org delete parameters_.config.encoder_settings.encoder; 1318b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void SetWebRtcFrameToBlack(webrtc::I420VideoFrame* video_frame) { 1321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(video_frame != NULL); 1322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 1323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 16, 1324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 1326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1328b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 1329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1332b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1333b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void CreateBlackFrame(webrtc::I420VideoFrame* video_frame, 1334b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1335b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1336b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->CreateEmptyFrame( 1337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org width, height, width, (width + 1) / 2, (width + 1) / 2); 1338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetWebRtcFrameToBlack(video_frame); 1339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void ConvertToI420VideoFrame(const VideoFrame& frame, 1342b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::I420VideoFrame* i420_frame) { 1343b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org i420_frame->CreateFrame( 1344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch() * frame.GetHeight()), 1345b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetYPlane(), 1346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch() * ((frame.GetHeight() + 1) / 2)), 1347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetUPlane(), 1348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch() * ((frame.GetHeight() + 1) / 2)), 1349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetVPlane(), 1350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetWidth()), 1351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetHeight()), 1352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch()), 1353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch()), 1354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch())); 1355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 1360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "InputFrame: " << frame->GetWidth() << "x" 1361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << frame->GetHeight(); 1362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org bool is_screencast = capturer->IsScreencast(); 1363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock before copying, can be called concurrently when swapping input source. 1364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope frame_cs(&frame_lock_); 1365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!muted_) { 1366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ConvertToI420VideoFrame(*frame, &video_frame_); 1367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Create a tiny black frame to transmit instead. 1369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org CreateBlackFrame(&video_frame_, 1, 1); 1370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org is_screencast = false; 1371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 13735301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ == NULL) { 13745301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org LOG(LS_WARNING) << "Capturer inputting frames before send codecs are " 13755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org "configured, dropping."; 13765301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org return; 13775301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 1379b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(format_.height == 0); 1380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (is_screencast) { 1385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetDimensions(video_frame_.width(), video_frame_.height()); 1386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1387b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SwapFrame: " << video_frame_.width() << "x" 1388b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << video_frame_.height() << " -> (codec) " 13896ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.video_streams.back().width << "x" 13906ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.video_streams.back().height; 1391b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Input()->SwapFrame(&video_frame_); 1392b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1395b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1398b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1399b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1400b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 1402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14035301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (capturer == NULL && stream_ != NULL) { 1404b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 1405b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::I420VideoFrame black_frame; 1406b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width = format_.width; 1408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height = format_.height; 1409b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int half_width = (width + 1) / 2; 1410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org black_frame.CreateEmptyFrame( 1411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org width, height, width, half_width, half_width); 1412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetWebRtcFrameToBlack(&black_frame); 1413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetDimensions(width, height); 1414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Input()->SwapFrame(&black_frame); 1415b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1416b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1417b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1418b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1423b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1424b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1431b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 1438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 14416ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 14446ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().max_framerate = 1445b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1446b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetDimensions(format.width, format.height); 1447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 1455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org bool was_muted = muted_; 1456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return was_muted != mute; 1458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1460b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1461b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 1462b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (capturer_ == NULL) { 1463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_->SignalVideoFrame.disconnect(this); 1466b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 14705301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( 14715301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 14725301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org talk_base::CritScope cs(&lock_); 14735301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org VideoCodecSettings codec_settings; 14745301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (parameters_.codec_settings.Get(&codec_settings)) { 14755301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, options); 14765301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } else { 14775301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.options = options; 14785301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 14795301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 1480b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 14815301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings) { 1482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 14835301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org SetCodecAndOptions(codec_settings, parameters_.options); 14845301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org} 14855301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( 14865301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoCodecSettings& codec_settings, 14875301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org const VideoOptions& options) { 14886ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org std::vector<webrtc::VideoStream> video_streams = 14896ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org encoder_factory_->CreateVideoStreams( 14905301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec, options, parameters_.config.rtp.ssrcs.size()); 14916ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (video_streams.empty()) { 1492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 14946ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams = video_streams; 14955301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org format_ = VideoFormat(codec_settings.codec.width, 14965301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org codec_settings.codec.height, 1497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 1498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 14996ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15006ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org webrtc::VideoEncoder* old_encoder = 15016ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config.encoder_settings.encoder; 15026ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config.encoder_settings.encoder = 15035301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org encoder_factory_->CreateVideoEncoder(codec_settings.codec, options); 15045301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 15055301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 15065301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.fec = codec_settings.fec; 15075301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15085301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org // Set RTX payload type if RTX is enabled. 15095301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 15105301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 15115301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15125301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15135301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (IsNackEnabled(codec_settings.codec)) { 15145301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.config.rtp.nack.rtp_history_ms = kNackHistoryMs; 15155301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 15165301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org 15175301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org parameters_.codec_settings.Set(codec_settings); 15186ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 1519b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 1520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete old_encoder; 1521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1522b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1523d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( 1524d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& rtp_extensions) { 1525d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org talk_base::CritScope cs(&lock_); 1526d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org parameters_.config.rtp.extensions = rtp_extensions; 1527d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1528d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1529d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1530b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions(int width, 15316ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org int height) { 15326ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org assert(!parameters_.video_streams.empty()); 1533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height; 15346ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (parameters_.video_streams.back().width == width && 15356ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().height == height) { 1536b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1537b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1539b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 15406ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().width = width; 15416ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().height = height; 15426ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15436f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 15446f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 15456f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org void* encoder_settings = encoder_factory_->CreateVideoEncoderSettings( 15466f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org codec_settings.codec, parameters_.options); 15476f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 15486f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org bool stream_reconfigured = stream_->ReconfigureVideoEncoder( 15496f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.video_streams, encoder_settings); 15506f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 15516f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings(codec_settings.codec, 15526f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_settings); 15536f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 15546f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org if (!stream_reconfigured) { 1555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 1556b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 1557b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1560b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1561b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 1562b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 15635301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org assert(stream_ != NULL); 1564b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 1566b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 1569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 15705301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org if (stream_ != NULL) { 15715301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org stream_->Stop(); 15725301b0f1fce9478dfa56476e174332a1d67b053apbos@webrtc.org } 1573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 1574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1576e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoSenderInfo 1577e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { 1578e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoSenderInfo info; 1579e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org talk_base::CritScope cs(&lock_); 1580e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (size_t i = 0; i < parameters_.config.rtp.ssrcs.size(); ++i) { 1581e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(parameters_.config.rtp.ssrcs[i]); 1582e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1583e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1584e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 1585e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_input = stats.input_frame_rate; 1586e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_sent = stats.encode_frame_rate; 1587e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1588e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org for (std::map<uint32_t, webrtc::StreamStats>::iterator it = 1589e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.substreams.begin(); 1590e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org it != stats.substreams.end(); 1591e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org ++it) { 1592e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Wire up additional stats, such as padding bytes. 1593e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::StreamStats stream_stats = it->second; 1594e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.bytes_sent += stream_stats.rtp_stats.bytes + 1595e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stream_stats.rtp_stats.header_bytes + 1596e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stream_stats.rtp_stats.padding_bytes; 1597e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_sent += stream_stats.rtp_stats.packets; 1598e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_lost += stream_stats.rtcp_stats.cumulative_lost; 1599e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1600e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1601e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (!stats.substreams.empty()) { 1602e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Report fraction lost per SSRC. 1603e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::StreamStats first_stream_stats = stats.substreams.begin()->second; 1604e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.fraction_lost = 1605e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 1606e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org (1 << 8); 1607e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1608e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1609e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org if (capturer_ != NULL && !capturer_->IsMuted()) { 1610e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoFormat last_captured_frame_format; 1611e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org capturer_->GetStats(&info.adapt_frame_drops, 1612e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &info.effects_frame_drops, 1613e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &info.capturer_frame_time, 1614e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org &last_captured_frame_format); 1615e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.input_frame_width = last_captured_frame_format.width; 1616e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.input_frame_height = last_captured_frame_format.height; 1617e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.send_frame_width = 1618e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<int>(parameters_.video_streams.front().width); 1619e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.send_frame_height = 1620e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org static_cast<int>(parameters_.video_streams.front().height); 1621e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org } 1622e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1623e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Support or remove the following stats. 1624e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_cached = -1; 1625e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.rtt_ms = -1; 1626e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1627e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 1628e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1629e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 1631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 1632b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 1633b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 16346ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 16356f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org VideoCodecSettings codec_settings; 16366f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.codec_settings.Get(&codec_settings); 16376f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org void* encoder_settings = encoder_factory_->CreateVideoEncoderSettings( 16386f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org codec_settings.codec, parameters_.options); 16396f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 16406ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org stream_ = call_->CreateVideoSendStream( 16416f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org parameters_.config, parameters_.video_streams, encoder_settings); 16426f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 16436f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_factory_->DestroyVideoEncoderSettings(codec_settings.codec, 16446f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org encoder_settings); 16456f48f1bf68a10669c9bcd81262c1a98ed2a8d462pbos@webrtc.org 1646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 1647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1650b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1651d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 1652d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::Call* call, 1653d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::VideoReceiveStream::Config& config, 1654d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) 1655d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org : call_(call), 1656d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_(config), 1657d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_(NULL), 1658d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_(-1), 1659d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_(-1), 1660d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_(NULL) { 1661d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.renderer = this; 1662d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // SetRecvCodecs will also reset (start) the VideoReceiveStream. 1663d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetRecvCodecs(recv_codecs); 1664d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1665d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1666d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { 1667d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1668d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1669d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1670d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRecvCodecs( 1671d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<VideoCodecSettings>& recv_codecs) { 1672d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 1673d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Base receive codecs off recv_codecs_ and set up using a 1674d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // DecoderFactory similar to send side. Pending webrtc:2854. 1675d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // Also set up default codecs if there's nothing in recv_codecs_. 1676d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org webrtc::VideoCodec codec; 1677d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org memset(&codec, 0, sizeof(codec)); 1678d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1679d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.plType = kDefaultVideoCodecPref.payload_type; 1680d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org strcpy(codec.plName, kDefaultVideoCodecPref.name); 1681d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecType = webrtc::kVideoCodecVP8; 1682d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.resilience = webrtc::kResilientStream; 1683d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.numberOfTemporalLayers = 1; 1684d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.denoisingOn = true; 1685d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.errorConcealmentOn = false; 1686d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.automaticResizeOn = false; 1687d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.frameDroppingOn = true; 1688d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.codecSpecific.VP8.keyFrameInterval = 3000; 1689d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // Bitrates don't matter and are ignored for the receiver. This is put in to 1690d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // have the current underlying implementation accept the VideoCodec. 1691d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org codec.minBitrate = codec.startBitrate = codec.maxBitrate = 300; 1692d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.codecs.clear(); 1693d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.codecs.push_back(codec); 1694d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1695d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.fec = recv_codecs.front().fec; 1696d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1697d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1698d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1699d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1700d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRtpExtensions( 1701d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const std::vector<webrtc::RtpExtension>& extensions) { 1702d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org config_.rtp.extensions = extensions; 1703d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org RecreateWebRtcStream(); 1704d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1705d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1706d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 1707d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (stream_ != NULL) { 1708d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org call_->DestroyVideoReceiveStream(stream_); 1709d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1710d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_ = call_->CreateVideoReceiveStream(config_); 1711d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org stream_->Start(); 1712d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1713d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1714d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::RenderFrame( 1715d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const webrtc::I420VideoFrame& frame, 1716d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int time_to_render_ms) { 1717d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org talk_base::CritScope crit(&renderer_lock_); 1718d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ == NULL) { 1719d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 1720d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return; 1721d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1722d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1723d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 1724d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(frame.width(), frame.height()); 1725d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1726d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1727d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_VERBOSE) << "RenderFrame: (" << frame.width() << "x" << frame.height() 1728d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org << ")"; 1729d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1730d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org const WebRtcVideoRenderFrame render_frame(&frame); 1731d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_->RenderFrame(&render_frame); 1732d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1733d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1734d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer( 1735d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org cricket::VideoRenderer* renderer) { 1736d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org talk_base::CritScope crit(&renderer_lock_); 1737d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org renderer_ = renderer; 1738d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 1739d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org SetSize(last_width_, last_height_); 1740d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1741d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1742d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1743d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgVideoRenderer* WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetRenderer() { 1744d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // TODO(pbos): Remove GetRenderer and all uses of it, it's thread-unsafe by 1745d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org // design. 1746d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org talk_base::CritScope crit(&renderer_lock_); 1747d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org return renderer_; 1748d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1749d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1750d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetSize(int width, 1751d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org int height) { 1752d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org talk_base::CritScope crit(&renderer_lock_); 1753d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 1754d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 1755d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org } 1756d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_width_ = width; 1757d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org last_height_ = height; 1758d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org} 1759d1ea06b3d5adab352741df5092c56b20f3e1a74fpbos@webrtc.org 1760e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgVideoReceiverInfo 1761e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { 1762e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org VideoReceiverInfo info; 1763e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.add_ssrc(config_.rtp.remote_ssrc); 1764e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); 1765e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.bytes_rcvd = stats.rtp_stats.bytes + stats.rtp_stats.header_bytes + 1766e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org stats.rtp_stats.padding_bytes; 1767e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_rcvd = stats.rtp_stats.packets; 1768e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1769e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_rcvd = stats.network_frame_rate; 1770e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_decoded = stats.decode_frame_rate; 1771e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.framerate_output = stats.render_frame_rate; 1772e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1773e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org talk_base::CritScope frame_cs(&renderer_lock_); 1774e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.frame_width = last_width_; 1775e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.frame_height = last_height_; 1776e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1777e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org // TODO(pbos): Support or remove the following stats. 1778e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org info.packets_concealed = -1; 1779e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1780e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org return info; 1781e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org} 1782e6f84ae8a602ce78733d20b280ce32198e7ecef5pbos@webrtc.org 1783b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 1784b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 1785b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1786b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 1787b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 1788b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!codecs.empty()); 1789b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1790b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 1791b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 1792e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org std::map<int, VideoCodec::CodecType> payload_codec_type; 1793b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, int> rtx_mapping; // video payload type -> rtx payload type. 1794b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1795b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 1796b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1797b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 1798b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 1799b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 1800b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1801b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 1802b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 1803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 1804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1805b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1806b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 1807e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org payload_codec_type[payload_type] = in_codec.GetCodecType(); 1808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 1810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 1811b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 1812b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.red_payload_type == -1); 1813b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 1814b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1815b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 1818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 1819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.ulpfec_payload_type == -1); 1820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 1821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1823b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 1825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 1826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 1827b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org &associated_payload_type)) { 1828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RTX codec without associated payload type: " 1829b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 1830b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1831b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1832b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 1833b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1834b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1835b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1836b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 1837b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 1838b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1839b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1840b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 1841b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 1842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 1845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 1846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!video_codecs.empty()); 1847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1848e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); 1849e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org it != rtx_mapping.end(); 1850e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org ++it) { 1851e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (!payload_used[it->first]) { 1852e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; 1853e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1854e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1855e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO) { 1856e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org LOG(LS_ERROR) << "RTX not mapped to regular video codec."; 1857e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1858e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1859e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org } 1860e322a175f6f38c4ed39296d9724edf005e536a63pbos@webrtc.org 1861b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Write tests that figure out that I have not verified that RTX 1862b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // codecs aren't mapped to bogus payloads. 1863b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 1864b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 1865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtx_mapping[video_codecs[i].codec.id] != 0) { 1866b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 1867b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1868b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1869b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 1871b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1873b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 1874b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 1875b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) { 1876b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 1877b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 1878b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (encoder_factory_->SupportsCodec(mapped_codecs[i].codec)) { 1879b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org supported_codecs.push_back(mapped_codecs[i]); 1880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return supported_codecs; 1883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1885b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 1886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 1888