webrtcvideoengine2.cc revision d41eaeb7cded2b2cda83f53aa320cf18e2d07380
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 31b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#ifdef HAVE_CONFIG_H 32b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include <config.h> 33b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif 34b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 35b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include <math.h> 36b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 37b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include <string> 38b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 39b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "libyuv/convert_from.h" 40b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/base/buffer.h" 41b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/base/logging.h" 42b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/base/stringutils.h" 43b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videocapturer.h" 44b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/base/videorenderer.h" 45b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideocapturer.h" 46b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvideoframe.h" 47b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "talk/media/webrtc/webrtcvoiceengine.h" 48b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/call.h" 49b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// TODO(pbos): Move codecs out of modules (webrtc:3070). 50b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" 51b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 52b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#define UNIMPLEMENTED \ 53b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Call to unimplemented function " << __FUNCTION__; \ 54b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(false) 55b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 56b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace cricket { 57b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 58b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kCpuMonitorPeriodMs = 2000; // 2 seconds. 59b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 60b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This constant is really an on/off, lower-level configurable NACK history 61b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// duration hasn't been implemented. 62b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kNackHistoryMs = 1000; 63b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 64b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultFramerate = 30; 65b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kMinVideoBitrate = 50; 66b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kMaxVideoBitrate = 2000; 67b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 68b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kVideoMtu = 1200; 69b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kVideoRtpBufferSize = 65536; 70b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 71b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const char kVp8PayloadName[] = "VP8"; 72b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 73b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic const int kDefaultRtcpReceiverReportSsrc = 1; 74b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 75b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstruct VideoCodecPref { 76b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type; 77b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const char* name; 78b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rtx_payload_type; 79b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} kDefaultVideoCodecPref = {100, kVp8PayloadName, 96}; 80b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 81b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoCodecPref kRedPref = {116, kRedCodecName, -1}; 82b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoCodecPref kUlpfecPref = {117, kUlpfecCodecName, -1}; 83b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 84b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// The formats are sorted by the descending order of width. We use the order to 85b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// find the next format for CPU and bandwidth adaptation. 86b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst VideoFormatPod kDefaultVideoFormat = { 87b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 640, 400, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}; 88b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst VideoFormatPod kVideoFormats[] = { 89b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {1280, 800, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 90b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {1280, 720, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 91b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {960, 600, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 92b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {960, 540, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 93b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoFormat, 94b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {640, 360, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 95b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {640, 480, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 96b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {480, 300, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 97b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {480, 270, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 98b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {480, 360, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 99b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {320, 200, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 100b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {320, 180, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 101b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {320, 240, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 102b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {240, 150, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 103b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {240, 135, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {240, 180, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 105b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {160, 100, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 106b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {160, 90, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, 107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org {160, 120, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, }; 108b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 109b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs, 110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& requested_codec, 111b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* matching_codec) { 112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested_codec.Matches(codecs[i])) { 114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *matching_codec = codecs[i]; 115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool FindBestVideoFormat(int max_width, 121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int max_height, 122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int aspect_width, 123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int aspect_height, 124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat* video_format) { 125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(max_width > 0); 126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(max_height > 0); 127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(aspect_width > 0); 128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(aspect_height > 0); 129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat best_format; 130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (int i = 0; i < ARRAY_SIZE(kVideoFormats); ++i) { 131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat format(kVideoFormats[i]); 132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Skip any format that is larger than the local or remote maximums, or 134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // smaller than the current best match 135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width > max_width || format.height > max_height || 136b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (format.width < best_format.width && 137b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.height < best_format.height)) { 138b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 139b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 140b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 141b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // If we don't have any matches yet, this is the best so far. 142b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (best_format.width == 0) { 143b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org best_format = format; 144b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 145b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 146b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 147b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Prefer closer aspect ratios i.e: 148b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // |format| aspect - requested aspect < 149b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // |best_format| aspect - requested aspect 150b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (abs(format.width * aspect_height * best_format.height - 151b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org aspect_width * format.height * best_format.height) < 152b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org abs(best_format.width * aspect_height * format.height - 153b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org aspect_width * format.height * best_format.height)) { 154b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org best_format = format; 155b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 156b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 157b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (best_format.width != 0) { 158b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *video_format = best_format; 159b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 160b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 161b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 162b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultVideoCodec() { 165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec default_codec(kDefaultVideoCodecPref.payload_type, 166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.name, 167b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoFormat.width, 168b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoFormat.height, 169b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultFramerate, 170b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 0); 171b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return default_codec; 172b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 173b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 174b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultRedCodec() { 175b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kRedPref.payload_type, kRedPref.name, 0, 0, 0, 0); 176b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 177b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 178b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic VideoCodec DefaultUlpfecCodec() { 179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoCodec(kUlpfecPref.payload_type, kUlpfecPref.name, 0, 0, 0, 0); 180b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 182b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic std::vector<VideoCodec> DefaultVideoCodecs() { 183b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodec> codecs; 184b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultVideoCodec()); 185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultRedCodec()); 186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back(DefaultUlpfecCodec()); 187b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (kDefaultVideoCodecPref.rtx_payload_type != -1) { 188b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codecs.push_back( 189b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec::CreateRtxCodec(kDefaultVideoCodecPref.rtx_payload_type, 190b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kDefaultVideoCodecPref.payload_type)); 191b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 192b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return codecs; 193b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 194b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1950d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.orgWebRtcVideoEncoderFactory2::~WebRtcVideoEncoderFactory2() { 1960d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org} 1970d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org 198d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgstd::vector<webrtc::VideoStream> WebRtcVideoEncoderFactory2::CreateVideoStreams( 199d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 200d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options, 201d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org size_t num_streams) { 202d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org assert(SupportsCodec(codec)); 203d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org if (num_streams != 1) { 204d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org LOG(LS_ERROR) << "Unsupported number of streams: " << num_streams; 205d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return std::vector<webrtc::VideoStream>(); 2066ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org } 207b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 208d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org webrtc::VideoStream stream; 209d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.width = codec.width; 210d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.height = codec.height; 211d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_framerate = 212d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.framerate != 0 ? codec.framerate : kDefaultFramerate; 213d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 214d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int min_bitrate = kMinVideoBitrate; 215d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMinBitrate, &min_bitrate); 216d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int max_bitrate = kMaxVideoBitrate; 217d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxBitrate, &max_bitrate); 218d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.min_bitrate_bps = min_bitrate * 1000; 219d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate * 1000; 220d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 221d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org int max_qp = 56; 222d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org codec.GetParam(kCodecParamMaxQuantization, &max_qp); 223d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org stream.max_qp = max_qp; 224d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org std::vector<webrtc::VideoStream> streams; 225d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org streams.push_back(stream); 226d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return streams; 227d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 228b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 229d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgwebrtc::VideoEncoder* WebRtcVideoEncoderFactory2::CreateVideoEncoder( 230d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoCodec& codec, 231d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org const VideoOptions& options) { 232d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org assert(SupportsCodec(codec)); 233d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return webrtc::VP8Encoder::Create(); 234d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 235d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org 236d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgbool WebRtcVideoEncoderFactory2::SupportsCodec(const VideoCodec& codec) { 237d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return _stricmp(codec.name.c_str(), kVp8PayloadName) == 0; 238d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org} 239b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 240b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2() { 241b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Construct without a factory or voice engine. 242b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(NULL, NULL, new talk_base::CpuMonitor(NULL)); 243b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 244b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 245b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::WebRtcVideoEngine2( 246b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoChannelFactory* channel_factory) { 247b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Construct without a voice engine. 248b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(channel_factory, NULL, new talk_base::CpuMonitor(NULL)); 249b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 250b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 251b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::Construct(WebRtcVideoChannelFactory* channel_factory, 252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVoiceEngine* voice_engine, 253b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CpuMonitor* cpu_monitor) { 254b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2"; 255b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org worker_thread_ = NULL; 256b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org voice_engine_ = voice_engine; 257b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = false; 258b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capture_started_ = false; 259b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_.reset(cpu_monitor); 260b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org channel_factory_ = channel_factory; 261b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 262b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs_ = DefaultVideoCodecs(); 263b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_codec_format_ = VideoFormat(kDefaultVideoFormat); 264b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 265b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 266b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::~WebRtcVideoEngine2() { 267b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; 268b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 269b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 270b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Terminate(); 271b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 272b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 273b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 274b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::Init(talk_base::Thread* worker_thread) { 275b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; 276b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org worker_thread_ = worker_thread; 277b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ASSERT(worker_thread_ != NULL); 278b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 279b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->set_thread(worker_thread_); 280b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!cpu_monitor_->Start(kCpuMonitorPeriodMs)) { 281b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Failed to start CPU monitor."; 282b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_.reset(); 283b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 284b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 285b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = true; 286b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 287b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 288b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 289b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::Terminate() { 290b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "WebRtcVideoEngine2::Terminate"; 291b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 292b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org cpu_monitor_->Stop(); 293b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 294b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org initialized_ = false; 295b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 296b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 297b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgint WebRtcVideoEngine2::GetCapabilities() { return VIDEO_RECV | VIDEO_SEND; } 298b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 299b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetOptions(const VideoOptions& options) { 300b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Do we need this? This is a no-op in the existing 301b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // WebRtcVideoEngine implementation. 302b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); 303b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // options_ = options; 304b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 307b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetDefaultEncoderConfig( 308b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoEncoderConfig& config) { 309b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. Should be covered by corresponding unit tests. 310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetDefaultEncoderConfig()"; 311b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 312b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoEncoderConfig WebRtcVideoEngine2::GetDefaultEncoderConfig() const { 315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return VideoEncoderConfig(DefaultVideoCodec()); 316b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 317b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 318b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( 319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel) { 320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "CreateChannel: " 321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (voice_channel != NULL ? "With" : "Without") 322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << " voice channel."; 323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoChannel2* channel = 324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org channel_factory_ != NULL 325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ? channel_factory_->Create(this, voice_channel) 326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : new WebRtcVideoChannel2( 3270d523eea831e616c415c61765127ed5eb17e5f11pbos@webrtc.org this, voice_channel, GetVideoEncoderFactory()); 328b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!channel->Init()) { 329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete channel; 330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 332b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return channel; 333b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 334b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 335b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<VideoCodec>& WebRtcVideoEngine2::codecs() const { 336b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs_; 337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgconst std::vector<RtpHeaderExtension>& 340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoEngine2::rtp_header_extensions() const { 341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return rtp_header_extensions_; 342b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 343b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 344b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoEngine2::SetLogging(int min_sev, const char* filter) { 345b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Set up logging. 346b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetLogging: " << min_sev << '"' << filter << '"'; 347b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if min_sev == -1, we keep the current log level. 348b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (min_sev < 0) { 349b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(min_sev == -1); 350b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 351b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 352b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 353b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::EnableTimedRender() { 355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Figure out whether this can be removed. 356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 357b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 358b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 359b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetLocalRenderer(VideoRenderer* renderer) { 360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement or remove. Unclear which stream should be rendered 361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // locally even. 362b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Checks to see whether we comprehend and could receive a particular codec 366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { 367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Probe encoder factory to figure out that the codec is supported 368b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // if supported by the encoder factory. Add a corresponding test that fails 369b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // with this code (that doesn't ask the factory). 370b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (int i = 0; i < ARRAY_SIZE(kVideoFormats); ++i) { 371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat fmt(kVideoFormats[i]); 372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((in.width != 0 || in.height != 0) && 373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (fmt.width != in.width || fmt.height != in.height)) { 374b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 375b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t j = 0; j < video_codecs_.size(); ++j) { 377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); 378b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (codec.Matches(in)) { 379b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Tells whether the |requested| codec can be transmitted or not. If it can be 387b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// transmitted |out| is set with the best settings supported. Aspect ratio will 388b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be set as close to |current|'s as possible. If not set |requested|'s 389b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// dimensions will be used for aspect ratio matching. 390b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::CanSendCodec(const VideoCodec& requested, 391b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& current, 392b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec* out) { 393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(out != NULL); 394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 395b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width != requested.height && 397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org (requested.height == 0 || requested.width == 0)) { 398b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // 0xn and nx0 are invalid resolutions. 399b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 400b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodec matching_codec; 403b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindFirstMatchingCodec(video_codecs_, requested, &matching_codec)) { 404b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Codec not supported. 405b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 406b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Pick the best quality that is within their and our bounds and has the 409b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // correct aspect ratio. 410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat format; 411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (requested.width == 0 && requested.height == 0) { 412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Special case with resolution 0. The channel should not send frames. 413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int max_width = talk_base::_min(requested.width, matching_codec.width); 415b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int max_height = talk_base::_min(requested.height, matching_codec.height); 416b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int aspect_width = max_width; 417b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int aspect_height = max_height; 418b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (current.width > 0 && current.height > 0) { 419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org aspect_width = current.width; 420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org aspect_height = current.height; 421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!FindBestVideoFormat( 423b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org max_width, max_height, aspect_width, aspect_height, &format)) { 424b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 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->width = format.width; 435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->height = format.height; 436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->params = requested.params; 437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out->feedback_params = requested.feedback_params; 438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::SetVoiceEngine(WebRtcVoiceEngine* voice_engine) { 442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (initialized_) { 443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "SetVoiceEngine can not be called after Init"; 444b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 445b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 446b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org voice_engine_ = voice_engine; 447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// gotten RTCP info yet from the remote side. 452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoEngine2::ShouldIgnoreTrace(const std::string& trace) { 453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static const char* const kTracesToIgnore[] = {NULL}; 454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (trace.find(*p) == 0) { 456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 460b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 461b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 462d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.orgWebRtcVideoEncoderFactory2* WebRtcVideoEngine2::GetVideoEncoderFactory() { 463d41eaeb7cded2b2cda83f53aa320cf18e2d07380buildbot@webrtc.org return &default_video_encoder_factory_; 464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 4666ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org// Thin map between VideoFrame and an existing webrtc::I420VideoFrame 467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// to avoid having to copy the rendered VideoFrame prematurely. 468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// This implementation is only safe to use in a const context and should never 469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// be written to. 4706ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgclass WebRtcVideoRenderFrame : public VideoFrame { 471b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org public: 472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org explicit WebRtcVideoRenderFrame(const webrtc::I420VideoFrame* frame) 473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : frame_(frame) {} 474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 475b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool InitToBlack(int w, 476b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 477b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 478b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 479b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 480b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) OVERRIDE { 481b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 483b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 484b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 485b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool Reset(uint32 fourcc, 486b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int w, 487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dw, 489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int dh, 490b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* sample, 491b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t sample_size, 492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp, 496b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int rotation) OVERRIDE { 497b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 500b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetWidth() const OVERRIDE { 502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->width()); 503b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 504b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetHeight() const OVERRIDE { 505b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return static_cast<size_t>(frame_->height()); 506b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 507b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 508b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetYPlane() const OVERRIDE { 509b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kYPlane); 510b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetUPlane() const OVERRIDE { 512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kUPlane); 513b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 514b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual const uint8* GetVPlane() const OVERRIDE { 515b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->buffer(webrtc::kVPlane); 516b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 517b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 518b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetYPlane() OVERRIDE { 519b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 522b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetUPlane() OVERRIDE { 523b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 525b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual uint8* GetVPlane() OVERRIDE { 527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 529b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 530b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 531b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetYPitch() const OVERRIDE { 532b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kYPlane); 533b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 534b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetUPitch() const OVERRIDE { 535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kUPlane); 536b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 537b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int32 GetVPitch() const OVERRIDE { 538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->stride(webrtc::kVPlane); 539b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 540b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 541b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void* GetNativeHandle() const OVERRIDE { return NULL; } 542b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 543b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelWidth() const OVERRIDE { return 1; } 544b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t GetPixelHeight() const OVERRIDE { return 1; } 545b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 546b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetElapsedTime() const OVERRIDE { 547b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert millisecond render time to ns timestamp. 548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame_->render_time_ms() * talk_base::kNumNanosecsPerMillisec; 549b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 550b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int64 GetTimeStamp() const OVERRIDE { 551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Convert 90K rtp timestamp to ns timestamp. 552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return (frame_->timestamp() / 90) * talk_base::kNumNanosecsPerMillisec; 553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 554b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetElapsedTime(int64 elapsed_time) OVERRIDE { UNIMPLEMENTED; } 555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual void SetTimeStamp(int64 time_stamp) OVERRIDE { UNIMPLEMENTED; } 556b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 557b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual int GetRotation() const OVERRIDE { 558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 559b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return ROTATION_0; 560b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 561b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 562b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* Copy() const OVERRIDE { 563b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 564b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return NULL; 565b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 566b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 567b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual bool MakeExclusive() OVERRIDE { 568b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 569b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t CopyToBuffer(uint8* buffer, size_t size) const { 573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org UNIMPLEMENTED; 574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; 575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(fbarchard): Refactor into base class and share with LMI 578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, 579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint8* buffer, 580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t size, 581b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int stride_rgb) const OVERRIDE { 582b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t width = GetWidth(); 583b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t height = GetHeight(); 584b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t needed = (stride_rgb >= 0 ? stride_rgb : -stride_rgb) * height; 585b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (size < needed) { 586b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "RGB buffer is not large enough"; 587b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 588b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 589b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 590b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (libyuv::ConvertFromI420(GetYPlane(), 591b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetYPitch(), 592b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPlane(), 593b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetUPitch(), 594b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPlane(), 595b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org GetVPitch(), 596b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org buffer, 597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stride_rgb, 598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(width), 599b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(height), 600b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org to_fourcc)) { 601b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RGB type not supported: " << to_fourcc; 602b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return 0; // 0 indicates error 603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return needed; 605b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 606b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org protected: 608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org virtual VideoFrame* CreateEmptyFrame(int w, 609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int h, 610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_width, 611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org size_t pixel_height, 612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 elapsed_time, 613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int64 time_stamp) const OVERRIDE { 614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Remove WebRtcVideoFrame dependency, and have a non-const 615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // version of I420VideoFrame wrapped. 616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoFrame* frame = new WebRtcVideoFrame(); 617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame->InitToBlack( 618b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org w, h, pixel_width, pixel_height, elapsed_time, time_stamp); 619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return frame; 620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org private: 623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const webrtc::I420VideoFrame* const frame_; 624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org}; 625b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoRenderer::WebRtcVideoRenderer() 627b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : last_width_(-1), last_height_(-1), renderer_(NULL) {} 628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 629b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoRenderer::RenderFrame(const webrtc::I420VideoFrame& frame, 630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int time_to_render_ms) { 631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope crit(&lock_); 632b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (renderer_ == NULL) { 633b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "VideoReceiveStream not connected to a VideoRenderer."; 634b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 635b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 636b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 637b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (frame.width() != last_width_ || frame.height() != last_height_) { 638b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetSize(frame.width(), frame.height()); 639b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 640b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 641b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "RenderFrame: (" << frame.width() << "x" << frame.height() 642b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << ")"; 643b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const WebRtcVideoRenderFrame render_frame(&frame); 645b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org renderer_->RenderFrame(&render_frame); 646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoRenderer::SetRenderer(cricket::VideoRenderer* renderer) { 649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope crit(&lock_); 650b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org renderer_ = renderer; 651b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (renderer_ != NULL && last_width_ != -1) { 652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetSize(last_width_, last_height_); 653b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 654b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 655b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 656b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgVideoRenderer* WebRtcVideoRenderer::GetRenderer() { 657b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope crit(&lock_); 658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return renderer_; 659b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoRenderer::SetSize(int width, int height) { 662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope crit(&lock_); 663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!renderer_->SetSize(width, height, 0)) { 664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Could not set renderer size."; 665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org last_width_ = width; 667b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org last_height_ = height; 668b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 669b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org// WebRtcVideoChannel2 671b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 672b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 673b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine, 674b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VoiceMediaChannel* voice_channel, 675b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : encoder_factory_(encoder_factory) { 677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Connect the video and audio with |voice_channel|. 678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call::Config config(this); 679b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(webrtc::Call::Create(config), engine); 680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoChannel2( 683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 684b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine, 685b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : encoder_factory_(encoder_factory) { 687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org Construct(call, engine); 688b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::Construct(webrtc::Call* call, 691b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEngine2* engine) { 692b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; 693b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 694b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_.reset(call); 695b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_renderer_ = NULL; 696b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 697b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_recv_ssrc_ = 0; 698b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 699b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 700b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::~WebRtcVideoChannel2() { 701b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 702b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 703b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 704b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 705b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 706b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 707b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 708b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, webrtc::VideoReceiveStream*>::iterator it = 709b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.begin(); 710b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != receive_streams_.end(); 711b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 712b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(it->second != NULL); 713b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoReceiveStream(it->second); 714b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 715b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 716b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoRenderer*>::iterator it = renderers_.begin(); 717b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != renderers_.end(); 718b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 719b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(it->second != NULL); 720b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 721b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 722b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 723b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 724b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::Init() { return true; } 725b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 726b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgnamespace { 727b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 728b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool ValidateCodecFormats(const std::vector<VideoCodec>& codecs) { 729b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 730b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!codecs[i].ValidateCodecFormat()) { 731b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 732b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 733b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 734b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 735b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 736b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 737b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { 738b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::stringstream out; 739b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << '{'; 740b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 741b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << codecs[i].ToString(); 742b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (i != codecs.size() - 1) { 743b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << ", "; 744b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 745b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 746b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org out << '}'; 747b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return out.str(); 748b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 749b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 750b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace 751b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 752b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 753b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Must these receive codecs propagate to existing receive 754b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // streams? 755b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRecvCodecs: " << CodecVectorToString(codecs); 756b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 757b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 758b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 759b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 760b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> mapped_codecs = MapCodecs(codecs); 761b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (mapped_codecs.empty()) { 762b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called without video codec payloads."; 763b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 764b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 765b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 766b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Add a decoder factory which controls supported codecs. 767b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Blocked on webrtc:2854. 768b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 769b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (_stricmp(mapped_codecs[i].codec.name.c_str(), kVp8PayloadName) != 0) { 770b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetRecvCodecs called with unsupported codec: '" 771b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << mapped_codecs[i].codec.name << "'"; 772b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 773b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 774b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 775b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 776b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org recv_codecs_ = mapped_codecs; 777b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 778b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 779b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 780b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 781b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); 782b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ValidateCodecFormats(codecs)) { 783b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 784b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 785b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 786b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<VideoCodecSettings> supported_codecs = 787b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FilterSupportedCodecs(MapCodecs(codecs)); 788b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 789b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (supported_codecs.empty()) { 790b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No video codecs supported by encoder factory."; 791b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 792b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 793b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 794b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_codec_.Set(supported_codecs.front()); 795b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); 796b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 797b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetCodecForAllSendStreams(supported_codecs.front()); 798b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 799b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 800b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 801b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 802b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { 803b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodecSettings codec_settings; 804b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 805b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; 806b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 807b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 808b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *codec = codec_settings.codec; 809b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 810b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 811b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 812b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendStreamFormat(uint32 ssrc, 813b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 814b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendStreamFormat:" << ssrc << " -> " 815b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << format.ToString(); 816b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 817b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 818b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 819b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetVideoFormat(format); 820b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 821b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 822b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRender(bool render) { 823b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. Or refactor away as it shouldn't be needed. 824b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetRender: " << (render ? "true" : "false"); 825b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 826b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 827b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 828b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSend(bool send) { 829b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSend: " << (send ? "true" : "false"); 830b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send && !send_codec_.IsSet()) { 831b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "SetSend(true) called before setting codec."; 832b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 833b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 834b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send) { 835b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StartAllSendStreams(); 836b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 837b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StopAllSendStreams(); 838b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 839b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = send; 840b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 841b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 842b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 843b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic bool ConfigureSendSsrcs(webrtc::VideoSendStream::Config* config, 844b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const StreamParams& sp) { 845b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!sp.has_ssrc_groups()) { 846b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config->rtp.ssrcs = sp.ssrcs; 847b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 848b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 849b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 850b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sp.get_ssrc_group(kFecSsrcGroupSemantics) != NULL) { 851b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Standalone FEC SSRCs not supported."; 852b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 853b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 854b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 855b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const SsrcGroup* sim_group = sp.get_ssrc_group(kSimSsrcGroupSemantics); 856b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sim_group == NULL) { 857b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Grouped StreamParams without regular SSRC group: " 858b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << sp.ToString(); 859b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 860b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 861b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 862b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Map RTX SSRCs. 863b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<uint32_t> rtx_ssrcs; 864b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < sim_group->ssrcs.size(); ++i) { 865b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32_t rtx_ssrc; 866b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!sp.GetFidSsrc(sim_group->ssrcs[i], &rtx_ssrc)) { 867b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 868b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 869b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_ssrcs.push_back(rtx_ssrc); 870b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 871b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!rtx_ssrcs.empty() && sim_group->ssrcs.size() != rtx_ssrcs.size()) { 872b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) 873b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 874b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << sp.ToString(); 875b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 876b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 877b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config->rtp.rtx.ssrcs = rtx_ssrcs; 878b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config->rtp.ssrcs = sim_group->ssrcs; 879b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 880b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 881b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 882b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { 883b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddSendStream: " << sp.ToString(); 884b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sp.ssrcs.empty()) { 885b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No SSRCs in stream parameters."; 886b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 887b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 888b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 889b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 890b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 891b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Make sure none of sp.ssrcs are used, not just the identifying 892b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ssrc. 893b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) != send_streams_.end()) { 894b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Send stream with ssrc '" << ssrc << "' already exists."; 895b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 896b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 897b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 898b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::VideoSendStream::Config config = call_->GetDefaultSendConfig(); 899b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 900b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!ConfigureSendSsrcs(&config, sp)) { 901b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 902b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 903b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 904b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCodecSettings codec_settings; 905b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!send_codec_.Get(&codec_settings)) { 906b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Set up a temporary fake encoder for VideoSendStream instead 907b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // of setting default codecs not to break CreateEncoderSettings. 908b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetSendCodecs(DefaultVideoCodecs()); 909b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(send_codec_.IsSet()); 910b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_codec_.Get(&codec_settings); 911b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // This is only to bring up defaults to make VideoSendStream setup easier 912b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // and avoid complexity. We still don't want to allow sending with the 913b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // default codec. 914b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_codec_.Clear(); 915b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 916b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 917b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // CreateEncoderSettings will allocate a suitable VideoEncoder instance 918b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // matching current settings. 9196ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org std::vector<webrtc::VideoStream> video_streams = 9206ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org encoder_factory_->CreateVideoStreams( 9216ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org codec_settings.codec, options_, config.rtp.ssrcs.size()); 9226ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (video_streams.empty()) { 923b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 924b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 925b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 9266ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org config.encoder_settings.encoder = 9276ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org encoder_factory_->CreateVideoEncoder(codec_settings.codec, options_); 9286ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org config.encoder_settings.payload_name = codec_settings.codec.name; 9296ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org config.encoder_settings.payload_type = codec_settings.codec.id; 930b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.c_name = sp.cname; 931b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.fec = codec_settings.fec; 932b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!config.rtp.rtx.ssrcs.empty()) { 933b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 934b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 935b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 936b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.nack.rtp_history_ms = kNackHistoryMs; 937b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.max_packet_size = kVideoMtu; 938b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 939b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoSendStream* stream = 9406ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org new WebRtcVideoSendStream(call_.get(), 9416ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org config, 9426ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options_, 9436ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org codec_settings.codec, 9446ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org video_streams, 9456ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org encoder_factory_); 946b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_[ssrc] = stream; 947b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 948b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { 949b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtcp_receiver_report_ssrc_ = ssrc; 950b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 951b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 952b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = ssrc; 953b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 954b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 955b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream->Start(); 956b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 957b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 958b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 959b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 960b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 961b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) { 962b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveSendStream: " << ssrc; 963b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 964b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 965b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_send_ssrc_ == 0) { 966b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No default send stream active."; 967b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 968b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 969b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 970b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Removing default stream: " << default_send_ssrc_; 971b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_send_ssrc_; 972b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 973b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 974b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<uint32, WebRtcVideoSendStream*>::iterator it = 975b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.find(ssrc); 976b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (it == send_streams_.end()) { 977b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 978b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 979b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 980b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete it->second; 981b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.erase(it); 982b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 983b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_send_ssrc_) { 984b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_send_ssrc_ = 0; 985b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 986b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 987b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 988b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 989b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 990b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { 991b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); 992b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(sp.ssrcs.size() > 0); 993b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 994b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = sp.first_ssrc(); 995b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); // TODO(pbos): Is this ever valid? 996b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_recv_ssrc_ == 0) { 997b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_recv_ssrc_ = ssrc; 998b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 999b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1000b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Check if any of the SSRCs overlap. 1001b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (receive_streams_.find(ssrc) != receive_streams_.end()) { 1002b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Receive stream for SSRC " << ssrc << "already exists."; 1003b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1004b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1005b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1006b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::VideoReceiveStream::Config config = call_->GetDefaultReceiveConfig(); 1007b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.remote_ssrc = ssrc; 1008b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.local_ssrc = rtcp_receiver_report_ssrc_; 1009b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 rtx_ssrc = 0; 1010b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 1011b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Right now, VideoReceiveStream accepts any rtx payload, this 1012b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // should use the actual codec payloads that may be received. 1013b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (for each receive payload, set rtx[payload].ssrc = rtx_ssrc. 1014b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.rtx[0].ssrc = rtx_ssrc; 1015b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1016b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1017198647473ba207d59dc94216ef38496d43d15592pbos@webrtc.org config.rtp.nack.rtp_history_ms = kNackHistoryMs; 1018b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.remb = true; 1019b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): This protection is against setting the same local ssrc as 1020b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // remote which is not permitted by the lower-level API. RTCP requires a 1021b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // corresponding sender SSRC. Figure out what to do when we don't have 1022b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // (receive-only) or know a good local SSRC. 1023b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (config.rtp.remote_ssrc == config.rtp.local_ssrc) { 1024b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (config.rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { 1025b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; 1026b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1027b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; 1028b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1029b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1030b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org bool default_renderer_used = false; 1031b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoRenderer*>::iterator it = renderers_.begin(); 1032b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != renderers_.end(); 1033b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1034b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (it->second->GetRenderer() == default_renderer_) { 1035b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_renderer_used = true; 1036b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 1037b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1038b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1039b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1040b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(renderers_[ssrc] == NULL); 1041b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org renderers_[ssrc] = new WebRtcVideoRenderer(); 1042b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!default_renderer_used) { 1043b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org renderers_[ssrc]->SetRenderer(default_renderer_); 1044b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1045b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.renderer = renderers_[ssrc]; 1046b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1047b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1048b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Base receive codecs off recv_codecs_ and set up using a 1049b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // DecoderFactory similar to send side. Pending webrtc:2854. 1050b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Also set up default codecs if there's nothing in recv_codecs_. 1051b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::VideoCodec codec; 1052b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(&codec, 0, sizeof(codec)); 1053b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1054b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codec.plType = kDefaultVideoCodecPref.payload_type; 1055b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org strcpy(codec.plName, kDefaultVideoCodecPref.name); 1056b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codec.codecType = webrtc::kVideoCodecVP8; 1057b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codec.codecSpecific.VP8.resilience = webrtc::kResilientStream; 1058b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codec.codecSpecific.VP8.numberOfTemporalLayers = 1; 1059b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codec.codecSpecific.VP8.denoisingOn = true; 1060b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codec.codecSpecific.VP8.errorConcealmentOn = false; 1061b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codec.codecSpecific.VP8.automaticResizeOn = false; 1062b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codec.codecSpecific.VP8.frameDroppingOn = true; 1063b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codec.codecSpecific.VP8.keyFrameInterval = 3000; 1064b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Bitrates don't matter and are ignored for the receiver. This is put in to 1065b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // have the current underlying implementation accept the VideoCodec. 1066b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codec.minBitrate = codec.startBitrate = codec.maxBitrate = 300; 1067b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.codecs.push_back(codec); 1068b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < recv_codecs_.size(); ++i) { 1069b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (recv_codecs_[i].codec.id == codec.plType) { 1070b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.fec = recv_codecs_[i].fec; 1071b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (recv_codecs_[i].rtx_payload_type != -1 && rtx_ssrc != 0) { 1072b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.rtx[codec.plType].ssrc = rtx_ssrc; 1073b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org config.rtp.rtx[codec.plType].payload_type = 1074b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org recv_codecs_[i].rtx_payload_type; 1075b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1076b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 1077b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1078b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1079b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1080b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1081b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::VideoReceiveStream* receive_stream = 1082b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->CreateVideoReceiveStream(config); 1083b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(receive_stream != NULL); 1084b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1085b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_[ssrc] = receive_stream; 1086b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_stream->Start(); 1087b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1088b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1089b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1090b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1091b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RemoveRecvStream(uint32 ssrc) { 1092b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 1093b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1094b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_recv_ssrc_; 1095b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1096b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1097b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<uint32, webrtc::VideoReceiveStream*>::iterator stream = 1098b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.find(ssrc); 1099b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream == receive_streams_.end()) { 1100b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Stream not found for ssrc: " << ssrc; 1101b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1102b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1103b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoReceiveStream(stream->second); 1104b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org receive_streams_.erase(stream); 1105b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1106b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<uint32, WebRtcVideoRenderer*>::iterator renderer = 1107b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org renderers_.find(ssrc); 1108b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(renderer != renderers_.end()); 1109b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete renderer->second; 1110b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org renderers_.erase(renderer); 1111b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1112b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == default_recv_ssrc_) { 1113b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_recv_ssrc_ = 0; 1114b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1115b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1116b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1117b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1118b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1119b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRenderer(uint32 ssrc, VideoRenderer* renderer) { 1120b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetRenderer: ssrc:" << ssrc << " " 1121b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (renderer ? "(ptr)" : "NULL"); 1122b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org bool is_default_ssrc = false; 1123b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1124b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org is_default_ssrc = true; 1125b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ssrc = default_recv_ssrc_; 1126b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org default_renderer_ = renderer; 1127b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1128b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1129b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<uint32, WebRtcVideoRenderer*>::iterator it = renderers_.find(ssrc); 1130b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (it == renderers_.end()) { 1131b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return is_default_ssrc; 1132b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1133b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1134b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetRenderer(renderer); 1135b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1136b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1137b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1138b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetRenderer(uint32 ssrc, VideoRenderer** renderer) { 1139b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (ssrc == 0) { 1140b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_renderer_ == NULL) { 1141b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1142b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1143b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = default_renderer_; 1144b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1145b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1146b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1147b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<uint32, WebRtcVideoRenderer*>::iterator it = renderers_.find(ssrc); 1148b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (it == renderers_.end()) { 1149b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1150b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1151b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org *renderer = it->second->GetRenderer(); 1152b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1153b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1154b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1155b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::GetStats(const StatsOptions& options, 1156b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoMediaInfo* info) { 1157b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1158b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1159b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1160b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1161b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 1162b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " 1163b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (capturer != NULL ? "(capturer)" : "NULL"); 1164b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1165b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1166b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1167b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1168b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1169b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->SetCapturer(capturer); 1170b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1171b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1172b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendIntraFrame() { 1173b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1174b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1175b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1176b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1177b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1178b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::RequestIntraFrame() { 1179b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1180b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SendIntraFrame()."; 1181b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1182b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1183b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1184b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnPacketReceived( 1185b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::Buffer* packet, 1186b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const talk_base::PacketTime& packet_time) { 11874e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org const webrtc::PacketReceiver::DeliveryStatus delivery_result = 11884e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org call_->Receiver()->DeliverPacket( 11894e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()); 11904e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org switch (delivery_result) { 11914e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_OK: 11924e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11934e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_PACKET_ERROR: 11944e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org return; 11954e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org case webrtc::PacketReceiver::DELIVERY_UNKNOWN_SSRC: 11964e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org break; 1197b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1198b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1199b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org uint32 ssrc = 0; 1200b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (default_recv_ssrc_ != 0) { // Already one default stream. 12014e545cc24478df6dec0f73cb8f5b9e5720fbce59pbos@webrtc.org LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set."; 1202b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1203b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1204b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1205b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!GetRtpSsrc(packet->data(), packet->length(), &ssrc)) { 1206b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1207b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1208b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1209b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org StreamParams sp; 1210b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sp.ssrcs.push_back(ssrc); 1211c34bb3a88627672d99b1c037d36dbeb23407fae4pbos@webrtc.org LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; 1212b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org AddRecvStream(sp); 1213b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 12141e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 12151e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 12161e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 12171e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTP packet after creating default " 12181e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org "receiver."; 1219b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1220b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1221b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1222b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1223b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnRtcpReceived( 1224b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::Buffer* packet, 1225b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const talk_base::PacketTime& packet_time) { 12261e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org if (call_->Receiver()->DeliverPacket( 12271e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org reinterpret_cast<const uint8_t*>(packet->data()), packet->length()) != 12281e019d10b8bcd96e8cf6b3d3df2730449fbed939pbos@webrtc.org webrtc::PacketReceiver::DELIVERY_OK) { 1229b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to deliver RTCP packet."; 1230b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1231b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1232b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1233b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnReadyToSend(bool ready) { 1234b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "OnReadySend: " << (ready ? "Ready." : "Not ready."); 1235b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1236b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1237b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::MuteStream(uint32 ssrc, bool mute) { 1238b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " 1239b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << (mute ? "mute" : "unmute"); 1240b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(ssrc != 0); 1241b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (send_streams_.find(ssrc) == send_streams_.end()) { 1242b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; 1243b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1244b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1245b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return send_streams_[ssrc]->MuteStream(mute); 1246b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1247b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1248b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetRecvRtpHeaderExtensions( 1249b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1250b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1251b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetRecvRtpHeaderExtensions()"; 1252b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1253b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1254b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1255b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( 1256b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 1257b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1258b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetSendRtpHeaderExtensions()"; 1259b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1260b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1261b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1262b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetStartSendBandwidth(int bps) { 1263b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1264b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetStartSendBandwidth: " << bps; 1265b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1266b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1267b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1268b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetMaxSendBandwidth(int bps) { 1269b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1270b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetMaxSendBandwidth: " << bps; 1271b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1272b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1273b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1274b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { 1275b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetOptions: " << options.ToString(); 1276b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org options_.SetAll(options); 1277b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1278b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1279b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1280b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { 1281b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetInterface(iface); 1282b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Set the RTP recv/send buffer to a bigger size 1283b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org MediaChannel::SetOption(NetworkInterface::ST_RTP, 1284b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::Socket::OPT_RCVBUF, 1285b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org kVideoRtpBufferSize); 1286b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1287b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(sriniv): Remove or re-enable this. 1288b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // As part of b/8030474, send-buffer is size now controlled through 1289b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // portallocator flags. 1290b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // network_interface_->SetOption(NetworkInterface::ST_RTP, 1291b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // talk_base::Socket::OPT_SNDBUF, 1292b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // kVideoRtpBufferSize); 1293b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1294b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1295b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::UpdateAspectRatio(int ratio_w, int ratio_h) { 1296b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Implement. 1297b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1298b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1299b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::OnMessage(talk_base::Message* msg) { 1300b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Ignored. 1301b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1302b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1303b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { 1304b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::Buffer packet(data, len, kMaxRtpPacketLen); 1305b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendPacket(&packet); 1306b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1307b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1308b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { 1309b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::Buffer packet(data, len, kMaxRtpPacketLen); 1310b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return MediaChannel::SendRtcp(&packet); 1311b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1312b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1313b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StartAllSendStreams() { 1314b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1315b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1316b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1317b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1318b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Start(); 1319b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1320b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1321b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1322b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::StopAllSendStreams() { 1323b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1324b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1325b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1326b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1327b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->Stop(); 1328b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1329b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1330b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1331b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::SetCodecForAllSendStreams( 1332b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const WebRtcVideoChannel2::VideoCodecSettings& codec) { 1333b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (std::map<uint32, WebRtcVideoSendStream*>::iterator it = 1334b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org send_streams_.begin(); 1335b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it != send_streams_.end(); 1336b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ++it) { 1337b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(it->second != NULL); 1338b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org it->second->SetCodec(options_, codec); 1339b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1340b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1341b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 13426ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 13436ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoSendStreamParameters( 13446ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const webrtc::VideoSendStream::Config& config, 13456ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 13466ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoCodec& codec, 13476ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const std::vector<webrtc::VideoStream>& video_streams) 13486ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org : config(config), 13496ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org options(options), 13506ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org codec(codec), 13516ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org video_streams(video_streams) { 13526ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org} 13536ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 1354b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( 1355b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::Call* call, 1356b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const webrtc::VideoSendStream::Config& config, 13576ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoOptions& options, 13586ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const VideoCodec& codec, 13596ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org const std::vector<webrtc::VideoStream>& video_streams, 1360b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org WebRtcVideoEncoderFactory2* encoder_factory) 1361b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : call_(call), 13626ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_(config, options, codec, video_streams), 1363b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org encoder_factory_(encoder_factory), 1364b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_(NULL), 1365b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_(NULL), 1366b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_(false), 1367b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_(false), 13686ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org format_(static_cast<int>(video_streams.back().height), 13696ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org static_cast<int>(video_streams.back().width), 13706ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org VideoFormat::FpsToInterval(video_streams.back().max_framerate), 1371b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420) { 1372b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 1373b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1374b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1375b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1376b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org DisconnectCapturer(); 1377b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 13786ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org delete parameters_.config.encoder_settings.encoder; 1379b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1380b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1381b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void SetWebRtcFrameToBlack(webrtc::I420VideoFrame* video_frame) { 1382b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(video_frame != NULL); 1383b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kYPlane), 1384b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 16, 1385b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kYPlane)); 1386b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kUPlane), 1387b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1388b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kUPlane)); 1389b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org memset(video_frame->buffer(webrtc::kVPlane), 1390b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 128, 1391b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->allocated_size(webrtc::kVPlane)); 1392b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1393b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1394b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void CreateBlackFrame(webrtc::I420VideoFrame* video_frame, 1395b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width, 1396b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height) { 1397b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_frame->CreateEmptyFrame( 1398b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org width, height, width, (width + 1) / 2, (width + 1) / 2); 1399b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetWebRtcFrameToBlack(video_frame); 1400b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1401b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1402b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstatic void ConvertToI420VideoFrame(const VideoFrame& frame, 1403b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::I420VideoFrame* i420_frame) { 1404b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org i420_frame->CreateFrame( 1405b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch() * frame.GetHeight()), 1406b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetYPlane(), 1407b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch() * ((frame.GetHeight() + 1) / 2)), 1408b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetUPlane(), 1409b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch() * ((frame.GetHeight() + 1) / 2)), 1410b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org frame.GetVPlane(), 1411b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetWidth()), 1412b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetHeight()), 1413b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetYPitch()), 1414b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetUPitch()), 1415b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org static_cast<int>(frame.GetVPitch())); 1416b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1417b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1418b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::InputFrame( 1419b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer, 1420b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFrame* frame) { 1421b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "InputFrame: " << frame->GetWidth() << "x" 1422b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << frame->GetHeight(); 1423b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org bool is_screencast = capturer->IsScreencast(); 1424b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock before copying, can be called concurrently when swapping input source. 1425b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope frame_cs(&frame_lock_); 1426b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!muted_) { 1427b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org ConvertToI420VideoFrame(*frame, &video_frame_); 1428b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1429b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Create a tiny black frame to transmit instead. 1430b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org CreateBlackFrame(&video_frame_, 1, 1); 1431b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org is_screencast = false; 1432b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1433b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 1434b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format_.width == 0) { // Dropping frames. 1435b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(format_.height == 0); 1436b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "VideoFormat 0x0 set, Dropping frame."; 1437b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1438b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1439b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Reconfigure codec if necessary. 1440b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (is_screencast) { 1441b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetDimensions(video_frame_.width(), video_frame_.height()); 1442b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1443b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SwapFrame: " << video_frame_.width() << "x" 1444b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << video_frame_.height() << " -> (codec) " 14456ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.video_streams.back().width << "x" 14466ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.video_streams.back().height; 1447b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Input()->SwapFrame(&video_frame_); 1448b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1449b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1450b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( 1451b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoCapturer* capturer) { 1452b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!DisconnectCapturer() && capturer == NULL) { 1453b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1454b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1455b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1456b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org { 1457b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 1458b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1459b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (capturer == NULL) { 1460b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 1461b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::I420VideoFrame black_frame; 1462b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1463b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int width = format_.width; 1464b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int height = format_.height; 1465b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int half_width = (width + 1) / 2; 1466b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org black_frame.CreateEmptyFrame( 1467b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org width, height, width, half_width, half_width); 1468b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetWebRtcFrameToBlack(&black_frame); 1469b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetDimensions(width, height); 1470b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Input()->SwapFrame(&black_frame); 1471b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1472b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1473b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1474b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1475b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1476b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = capturer; 1477b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1478b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // Lock cannot be held while connecting the capturer to prevent lock-order 1479b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // violations. 1480b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); 1481b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1482b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1483b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1484b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( 1485b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoFormat& format) { 1486b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if ((format.width == 0 || format.height == 0) && 1487b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format.width != format.height) { 1488b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " 1489b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org "both, 0x0 drops frames)."; 1490b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1491b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1492b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1493b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 1494b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (format.width == 0 && format.height == 0) { 1495b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_INFO) 1496b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << "0x0 resolution selected. Captured frames will be dropped for ssrc: " 14976ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org << parameters_.config.rtp.ssrcs[0] << "."; 1498b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } else { 1499b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 15006ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().max_framerate = 1501b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::IntervalToFps(format.interval); 1502b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org SetDimensions(format.width, format.height); 1503b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1504b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1505b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = format; 1506b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1507b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1508b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1509b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { 1510b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 1511b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org bool was_muted = muted_; 1512b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org muted_ = mute; 1513b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return was_muted != mute; 1514b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1515b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1516b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgbool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { 1517b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 1518b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (capturer_ == NULL) { 1519b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return false; 1520b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1521b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_->SignalVideoFrame.disconnect(this); 1522b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org capturer_ = NULL; 1523b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return true; 1524b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1525b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1526b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 1527b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoOptions& options, 1528b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodecSettings& codec) { 1529b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 15306ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15316ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org std::vector<webrtc::VideoStream> video_streams = 15326ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org encoder_factory_->CreateVideoStreams( 15336ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org codec.codec, options, parameters_.video_streams.size()); 15346ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (video_streams.empty()) { 1535b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1536b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 15376ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams = video_streams; 1538b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org format_ = VideoFormat(codec.codec.width, 1539b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org codec.codec.height, 1540b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org VideoFormat::FpsToInterval(30), 1541b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org FOURCC_I420); 15426ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15436ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org webrtc::VideoEncoder* old_encoder = 15446ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config.encoder_settings.encoder; 15456ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config.encoder_settings.encoder = 15466ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org encoder_factory_->CreateVideoEncoder(codec.codec, options); 15476ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config.rtp.fec = codec.fec; 1548b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Should changing RTX payload type be allowed? 15496ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.codec = codec.codec; 15506ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.options = options; 1551b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org RecreateWebRtcStream(); 1552b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org delete old_encoder; 1553b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1554b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1555b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions(int width, 15566ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org int height) { 15576ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org assert(!parameters_.video_streams.empty()); 1558b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_VERBOSE) << "SetDimensions: " << width << "x" << height; 15596ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (parameters_.video_streams.back().width == width && 15606ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().height == height) { 1561b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1562b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1563b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1564b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Fix me, this only affects the last stream! 15656ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().width = width; 15666ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.video_streams.back().height = height; 15676ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15686ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org // TODO(pbos): Wire up encoder_parameters, webrtc:3424. 15696ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org if (!stream_->ReconfigureVideoEncoder(parameters_.video_streams, NULL)) { 1570b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " 1571b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << width << "x" << height; 1572b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return; 1573b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1574b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1575b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1576b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Start() { 1577b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 1578b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1579b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = true; 1580b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1581b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1582b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::Stop() { 1583b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org talk_base::CritScope cs(&lock_); 1584b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Stop(); 1585b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org sending_ = false; 1586b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1587b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1588b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgvoid WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 1589b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (stream_ != NULL) { 1590b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org call_->DestroyVideoSendStream(stream_); 1591b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 15926ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org 15936ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org // TODO(pbos): Wire up encoder_parameters, webrtc:3424. 15946ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org stream_ = call_->CreateVideoSendStream( 15956ae48c660934784b4df56ab1ac99402ce3745e9fpbos@webrtc.org parameters_.config, parameters_.video_streams, NULL); 1596b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (sending_) { 1597b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org stream_->Start(); 1598b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1599b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1600b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1601b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 1602b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org : rtx_payload_type(-1) {} 1603b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1604b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 1605b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 1606b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!codecs.empty()); 1607b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1608b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> video_codecs; 1609b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, bool> payload_used; 1610b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::map<int, int> rtx_mapping; // video payload type -> rtx payload type. 1611b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1612b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org webrtc::FecConfig fec_settings; 1613b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1614b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < codecs.size(); ++i) { 1615b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const VideoCodec& in_codec = codecs[i]; 1616b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int payload_type = in_codec.id; 1617b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1618b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (payload_used[payload_type]) { 1619b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "Payload type already registered: " 1620b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 1621b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1622b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1623b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org payload_used[payload_type] = true; 1624b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1625b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org switch (in_codec.GetCodecType()) { 1626b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RED: { 1627b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // RED payload type, should not have duplicates. 1628b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.red_payload_type == -1); 1629b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.red_payload_type = in_codec.id; 1630b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1631b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1632b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1633b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_ULPFEC: { 1634b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // ULPFEC payload type, should not have duplicates. 1635b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(fec_settings.ulpfec_payload_type == -1); 1636b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org fec_settings.ulpfec_payload_type = in_codec.id; 1637b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1638b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1639b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1640b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_RTX: { 1641b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org int associated_payload_type; 1642b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 1643b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org &associated_payload_type)) { 1644b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org LOG(LS_ERROR) << "RTX codec without associated payload type: " 1645b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org << in_codec.ToString(); 1646b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return std::vector<VideoCodecSettings>(); 1647b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1648b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org rtx_mapping[associated_payload_type] = in_codec.id; 1649b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org continue; 1650b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1651b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1652b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org case VideoCodec::CODEC_VIDEO: 1653b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org break; 1654b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1655b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1656b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.push_back(VideoCodecSettings()); 1657b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs.back().codec = in_codec; 1658b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1659b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1660b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // One of these codecs should have been a video codec. Only having FEC 1661b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // parameters into this code is a logic error. 1662b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org assert(!video_codecs.empty()); 1663b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1664b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // TODO(pbos): Write tests that figure out that I have not verified that RTX 1665b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org // codecs aren't mapped to bogus payloads. 1666b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < video_codecs.size(); ++i) { 1667b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].fec = fec_settings; 1668b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (rtx_mapping[video_codecs[i].codec.id] != 0) { 1669b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 1670b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1671b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1672b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1673b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return video_codecs; 1674b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1675b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1676b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgstd::vector<WebRtcVideoChannel2::VideoCodecSettings> 1677b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.orgWebRtcVideoChannel2::FilterSupportedCodecs( 1678b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) { 1679b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org std::vector<VideoCodecSettings> supported_codecs; 1680b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org for (size_t i = 0; i < mapped_codecs.size(); ++i) { 1681b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org if (encoder_factory_->SupportsCodec(mapped_codecs[i].codec)) { 1682b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org supported_codecs.push_back(mapped_codecs[i]); 1683b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1684b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org } 1685b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org return supported_codecs; 1686b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} 1687b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1688b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org} // namespace cricket 1689b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org 1690b5a22b14648c53874b4b76368a1a2271d985e875pbos@webrtc.org#endif // HAVE_WEBRTC_VIDEO 1691