Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(208)

Side by Side Diff: webrtc/media/engine/webrtcvideoengine2.cc

Issue 2511703002: Wire up FlexFEC in VideoEngine2. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 21 matching lines...) Expand all
32 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" 32 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
33 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" 33 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h"
34 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" 34 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
35 #include "webrtc/system_wrappers/include/field_trial.h" 35 #include "webrtc/system_wrappers/include/field_trial.h"
36 #include "webrtc/video_decoder.h" 36 #include "webrtc/video_decoder.h"
37 #include "webrtc/video_encoder.h" 37 #include "webrtc/video_encoder.h"
38 38
39 namespace cricket { 39 namespace cricket {
40 namespace { 40 namespace {
41 41
42 // Three things happen when the FlexFEC field trial is enabled:
43 // 1) FlexFEC is exposed in the default codec list, eventually showing up
44 // in the default SDP.
45 // 2) FlexFEC send parameters are set in the VideoSendStream config.
46 // 3) FlexFEC receive parameters are set in the FlexfecReceiveStream config,
47 // and the corresponding object is instantiated.
48 const char kFlexfecFieldTrialName[] = "WebRTC-FlexFEC-03";
49
50 bool IsFlexfecEnabled() {
51 return webrtc::field_trial::FindFullName(kFlexfecFieldTrialName) == "Enabled";
52 }
53
42 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. 54 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory.
43 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { 55 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory {
44 public: 56 public:
45 // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned 57 // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned
46 // by e.g. PeerConnectionFactory. 58 // by e.g. PeerConnectionFactory.
47 explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory) 59 explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory)
48 : factory_(factory) {} 60 : factory_(factory) {}
49 virtual ~EncoderFactoryAdapter() {} 61 virtual ~EncoderFactoryAdapter() {}
50 62
51 // Implement webrtc::VideoEncoderFactory. 63 // Implement webrtc::VideoEncoderFactory.
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 AddCodecAndMaybeRtxCodec( 445 AddCodecAndMaybeRtxCodec(
434 MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, kVp8CodecName), 446 MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, kVp8CodecName),
435 &codecs); 447 &codecs);
436 if (webrtc::VP9Encoder::IsSupported() && webrtc::VP9Decoder::IsSupported()) { 448 if (webrtc::VP9Encoder::IsSupported() && webrtc::VP9Decoder::IsSupported()) {
437 AddCodecAndMaybeRtxCodec(MakeVideoCodecWithDefaultFeedbackParams( 449 AddCodecAndMaybeRtxCodec(MakeVideoCodecWithDefaultFeedbackParams(
438 kDefaultVp9PlType, kVp9CodecName), 450 kDefaultVp9PlType, kVp9CodecName),
439 &codecs); 451 &codecs);
440 } 452 }
441 if (webrtc::H264Encoder::IsSupported() && 453 if (webrtc::H264Encoder::IsSupported() &&
442 webrtc::H264Decoder::IsSupported()) { 454 webrtc::H264Decoder::IsSupported()) {
443 VideoCodec codec = MakeVideoCodecWithDefaultFeedbackParams( 455 VideoCodec h264_codec = MakeVideoCodecWithDefaultFeedbackParams(
444 kDefaultH264PlType, kH264CodecName); 456 kDefaultH264PlType, kH264CodecName);
445 // TODO(hta): Move all parameter generation for SDP into the codec 457 // TODO(hta): Move all parameter generation for SDP into the codec
446 // implementation, for all codecs and parameters. 458 // implementation, for all codecs and parameters.
447 // TODO(hta): Move selection of profile-level-id to H.264 codec 459 // TODO(hta): Move selection of profile-level-id to H.264 codec
448 // implementation. 460 // implementation.
449 // TODO(hta): Set FMTP parameters for all codecs of type H264. 461 // TODO(hta): Set FMTP parameters for all codecs of type H264.
450 codec.SetParam(kH264FmtpProfileLevelId, 462 h264_codec.SetParam(kH264FmtpProfileLevelId,
451 kH264ProfileLevelConstrainedBaseline); 463 kH264ProfileLevelConstrainedBaseline);
452 codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1"); 464 h264_codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1");
453 codec.SetParam(kH264FmtpPacketizationMode, "1"); 465 h264_codec.SetParam(kH264FmtpPacketizationMode, "1");
454 AddCodecAndMaybeRtxCodec(codec, &codecs); 466 AddCodecAndMaybeRtxCodec(h264_codec, &codecs);
455 } 467 }
456 AddCodecAndMaybeRtxCodec(VideoCodec(kDefaultRedPlType, kRedCodecName), 468 AddCodecAndMaybeRtxCodec(VideoCodec(kDefaultRedPlType, kRedCodecName),
457 &codecs); 469 &codecs);
458 codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName)); 470 codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName));
471
472 if (IsFlexfecEnabled()) {
473 VideoCodec flexfec_codec(kDefaultFlexfecPlType, kFlexfecCodecName);
474 flexfec_codec.SetParam(kFlexfecFmtpRepairWindow, "10000000");
stefan-webrtc 2016/11/17 12:48:59 Comment on how this window size was chosen.
brandtr 2016/11/17 13:23:36 Done.
475 codecs.push_back(flexfec_codec);
476 }
477
459 return codecs; 478 return codecs;
460 } 479 }
461 480
462 static std::vector<VideoCodec> GetSupportedCodecs( 481 static std::vector<VideoCodec> GetSupportedCodecs(
463 const WebRtcVideoEncoderFactory* external_encoder_factory); 482 const WebRtcVideoEncoderFactory* external_encoder_factory);
464 483
465 rtc::scoped_refptr<webrtc::VideoEncoderConfig::EncoderSpecificSettings> 484 rtc::scoped_refptr<webrtc::VideoEncoderConfig::EncoderSpecificSettings>
466 WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( 485 WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings(
467 const VideoCodec& codec) { 486 const VideoCodec& codec) {
468 RTC_DCHECK_RUN_ON(&thread_checker_); 487 RTC_DCHECK_RUN_ON(&thread_checker_);
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 receive_streams_.erase(prev_stream); 1246 receive_streams_.erase(prev_stream);
1228 } 1247 }
1229 1248
1230 if (!ValidateReceiveSsrcAvailability(sp)) 1249 if (!ValidateReceiveSsrcAvailability(sp))
1231 return false; 1250 return false;
1232 1251
1233 for (uint32_t used_ssrc : sp.ssrcs) 1252 for (uint32_t used_ssrc : sp.ssrcs)
1234 receive_ssrcs_.insert(used_ssrc); 1253 receive_ssrcs_.insert(used_ssrc);
1235 1254
1236 webrtc::VideoReceiveStream::Config config(this); 1255 webrtc::VideoReceiveStream::Config config(this);
1237 ConfigureReceiverRtp(&config, sp); 1256 webrtc::FlexfecConfig flexfec_config;
1257 ConfigureReceiverRtp(&config, &flexfec_config, sp);
1238 1258
1239 // Set up A/V sync group based on sync label. 1259 // Set up A/V sync group based on sync label.
1240 config.sync_group = sp.sync_label; 1260 config.sync_group = sp.sync_label;
1241 1261
1242 config.rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false; 1262 config.rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false;
1243 config.rtp.transport_cc = 1263 config.rtp.transport_cc =
1244 send_codec_ ? HasTransportCc(send_codec_->codec) : false; 1264 send_codec_ ? HasTransportCc(send_codec_->codec) : false;
1245 config.disable_prerenderer_smoothing = 1265 config.disable_prerenderer_smoothing =
1246 video_config_.disable_prerenderer_smoothing; 1266 video_config_.disable_prerenderer_smoothing;
1247 1267
1248 receive_streams_[ssrc] = new WebRtcVideoReceiveStream( 1268 receive_streams_[ssrc] = new WebRtcVideoReceiveStream(
1249 call_, sp, std::move(config), external_decoder_factory_, default_stream, 1269 call_, sp, std::move(config), external_decoder_factory_, default_stream,
1250 recv_codecs_); 1270 recv_codecs_, flexfec_config);
1251 1271
1252 return true; 1272 return true;
1253 } 1273 }
1254 1274
1255 void WebRtcVideoChannel2::ConfigureReceiverRtp( 1275 void WebRtcVideoChannel2::ConfigureReceiverRtp(
1256 webrtc::VideoReceiveStream::Config* config, 1276 webrtc::VideoReceiveStream::Config* config,
1277 webrtc::FlexfecConfig* flexfec_config,
1257 const StreamParams& sp) const { 1278 const StreamParams& sp) const {
1258 uint32_t ssrc = sp.first_ssrc(); 1279 uint32_t ssrc = sp.first_ssrc();
1259 1280
1260 config->rtp.remote_ssrc = ssrc; 1281 config->rtp.remote_ssrc = ssrc;
1261 config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 1282 config->rtp.local_ssrc = rtcp_receiver_report_ssrc_;
1262 1283
1263 config->rtp.extensions = recv_rtp_extensions_; 1284 config->rtp.extensions = recv_rtp_extensions_;
1264 // Whether or not the receive stream sends reduced size RTCP is determined 1285 // Whether or not the receive stream sends reduced size RTCP is determined
1265 // by the send params. 1286 // by the send params.
1266 // TODO(deadbeef): Once we change "send_params" to "sender_params" and 1287 // TODO(deadbeef): Once we change "send_params" to "sender_params" and
(...skipping 18 matching lines...) Expand all
1285 for (size_t i = 0; i < recv_codecs_.size(); ++i) { 1306 for (size_t i = 0; i < recv_codecs_.size(); ++i) {
1286 uint32_t rtx_ssrc; 1307 uint32_t rtx_ssrc;
1287 if (recv_codecs_[i].rtx_payload_type != -1 && 1308 if (recv_codecs_[i].rtx_payload_type != -1 &&
1288 sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 1309 sp.GetFidSsrc(ssrc, &rtx_ssrc)) {
1289 webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = 1310 webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx =
1290 config->rtp.rtx[recv_codecs_[i].codec.id]; 1311 config->rtp.rtx[recv_codecs_[i].codec.id];
1291 rtx.ssrc = rtx_ssrc; 1312 rtx.ssrc = rtx_ssrc;
1292 rtx.payload_type = recv_codecs_[i].rtx_payload_type; 1313 rtx.payload_type = recv_codecs_[i].rtx_payload_type;
1293 } 1314 }
1294 } 1315 }
1316
1317 // TODO(brandtr): This code needs to be generalized when we add support for
1318 // multistream protection.
1319 uint32_t flexfec_ssrc;
1320 if (sp.GetFecFrSsrc(ssrc, &flexfec_ssrc)) {
1321 flexfec_config->flexfec_ssrc = flexfec_ssrc;
1322 flexfec_config->protected_media_ssrcs = {ssrc};
1323 }
1295 } 1324 }
1296 1325
1297 bool WebRtcVideoChannel2::RemoveRecvStream(uint32_t ssrc) { 1326 bool WebRtcVideoChannel2::RemoveRecvStream(uint32_t ssrc) {
1298 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 1327 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc;
1299 if (ssrc == 0) { 1328 if (ssrc == 0) {
1300 LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 1329 LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported.";
1301 return false; 1330 return false;
1302 } 1331 }
1303 1332
1304 rtc::CritScope stream_lock(&stream_crit_); 1333 rtc::CritScope stream_lock(&stream_crit_);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { 1471 if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) {
1443 return; 1472 return;
1444 } 1473 }
1445 1474
1446 int payload_type = 0; 1475 int payload_type = 0;
1447 if (!GetRtpPayloadType(packet->cdata(), packet->size(), &payload_type)) { 1476 if (!GetRtpPayloadType(packet->cdata(), packet->size(), &payload_type)) {
1448 return; 1477 return;
1449 } 1478 }
1450 1479
1451 // See if this payload_type is registered as one that usually gets its own 1480 // See if this payload_type is registered as one that usually gets its own
1452 // SSRC (RTX) or at least is safe to drop either way (ULPFEC). If it is, and 1481 // SSRC (RTX) or at least is safe to drop either way (FEC). If it is, and
1453 // it wasn't handled above by DeliverPacket, that means we don't know what 1482 // it wasn't handled above by DeliverPacket, that means we don't know what
1454 // stream it associates with, and we shouldn't ever create an implicit channel 1483 // stream it associates with, and we shouldn't ever create an implicit channel
1455 // for these. 1484 // for these.
1456 for (auto& codec : recv_codecs_) { 1485 for (auto& codec : recv_codecs_) {
1457 if (payload_type == codec.rtx_payload_type || 1486 if (payload_type == codec.rtx_payload_type ||
1458 payload_type == codec.ulpfec.red_rtx_payload_type || 1487 payload_type == codec.ulpfec.red_rtx_payload_type ||
1459 payload_type == codec.ulpfec.ulpfec_payload_type) { 1488 payload_type == codec.ulpfec.ulpfec_payload_type ||
1489 payload_type == codec.flexfec.flexfec_payload_type) {
1460 return; 1490 return;
1461 } 1491 }
1462 } 1492 }
1463 1493
1464 switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 1494 switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) {
1465 case UnsignalledSsrcHandler::kDropPacket: 1495 case UnsignalledSsrcHandler::kDropPacket:
1466 return; 1496 return;
1467 case UnsignalledSsrcHandler::kDeliverPacket: 1497 case UnsignalledSsrcHandler::kDeliverPacket:
1468 break; 1498 break;
1469 } 1499 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 encoder_sink_(nullptr), 1622 encoder_sink_(nullptr),
1593 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), 1623 parameters_(std::move(config), options, max_bitrate_bps, codec_settings),
1594 rtp_parameters_(CreateRtpParametersWithOneEncoding()), 1624 rtp_parameters_(CreateRtpParametersWithOneEncoding()),
1595 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), 1625 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false),
1596 sending_(false), 1626 sending_(false),
1597 last_frame_timestamp_us_(0) { 1627 last_frame_timestamp_us_(0) {
1598 parameters_.config.rtp.max_packet_size = kVideoMtu; 1628 parameters_.config.rtp.max_packet_size = kVideoMtu;
1599 parameters_.conference_mode = send_params.conference_mode; 1629 parameters_.conference_mode = send_params.conference_mode;
1600 1630
1601 sp.GetPrimarySsrcs(&parameters_.config.rtp.ssrcs); 1631 sp.GetPrimarySsrcs(&parameters_.config.rtp.ssrcs);
1632
1633 // RTX.
1602 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 1634 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs,
1603 &parameters_.config.rtp.rtx.ssrcs); 1635 &parameters_.config.rtp.rtx.ssrcs);
1636
1637 // FlexFEC.
1638 // TODO(brandtr): This code needs to be generalized when we add support for
1639 // multistream protection.
1640 if (IsFlexfecEnabled()) {
1641 uint32_t flexfec_ssrc;
1642 bool flexfec_enabled = false;
1643 for (uint32_t primary_ssrc : parameters_.config.rtp.ssrcs) {
1644 if (sp.GetFecFrSsrc(primary_ssrc, &flexfec_ssrc)) {
1645 if (flexfec_enabled) {
1646 LOG(LS_INFO) << "Multiple FlexFEC streams proposed by remote, but "
1647 "our implementation only supports a single FlexFEC "
1648 "stream. Will not enable FlexFEC for proposed "
1649 "stream with SSRC: "
1650 << flexfec_ssrc << ".";
1651 continue;
1652 }
1653
1654 flexfec_enabled = true;
1655 parameters_.config.rtp.flexfec.flexfec_ssrc = flexfec_ssrc;
1656 parameters_.config.rtp.flexfec.protected_media_ssrcs = {primary_ssrc};
1657 }
1658 }
1659 }
1660
1604 parameters_.config.rtp.c_name = sp.cname; 1661 parameters_.config.rtp.c_name = sp.cname;
1605 if (rtp_extensions) { 1662 if (rtp_extensions) {
1606 parameters_.config.rtp.extensions = *rtp_extensions; 1663 parameters_.config.rtp.extensions = *rtp_extensions;
1607 } 1664 }
1608 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size 1665 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size
1609 ? webrtc::RtcpMode::kReducedSize 1666 ? webrtc::RtcpMode::kReducedSize
1610 : webrtc::RtcpMode::kCompound; 1667 : webrtc::RtcpMode::kCompound;
1611 if (codec_settings) { 1668 if (codec_settings) {
1612 SetCodec(*codec_settings); 1669 SetCodec(*codec_settings);
1613 } 1670 }
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1778 parameters_.config.encoder_settings.encoder = new_encoder.encoder; 1835 parameters_.config.encoder_settings.encoder = new_encoder.encoder;
1779 parameters_.config.encoder_settings.full_overuse_time = new_encoder.external; 1836 parameters_.config.encoder_settings.full_overuse_time = new_encoder.external;
1780 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 1837 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name;
1781 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 1838 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id;
1782 if (new_encoder.external) { 1839 if (new_encoder.external) {
1783 webrtc::VideoCodecType type = CodecTypeFromName(codec_settings.codec.name); 1840 webrtc::VideoCodecType type = CodecTypeFromName(codec_settings.codec.name);
1784 parameters_.config.encoder_settings.internal_source = 1841 parameters_.config.encoder_settings.internal_source =
1785 external_encoder_factory_->EncoderTypeHasInternalSource(type); 1842 external_encoder_factory_->EncoderTypeHasInternalSource(type);
1786 } 1843 }
1787 parameters_.config.rtp.ulpfec = codec_settings.ulpfec; 1844 parameters_.config.rtp.ulpfec = codec_settings.ulpfec;
1845 parameters_.config.rtp.flexfec.flexfec_payload_type =
1846 codec_settings.flexfec.flexfec_payload_type;
1788 1847
1789 // Set RTX payload type if RTX is enabled. 1848 // Set RTX payload type if RTX is enabled.
1790 if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 1849 if (!parameters_.config.rtp.rtx.ssrcs.empty()) {
1791 if (codec_settings.rtx_payload_type == -1) { 1850 if (codec_settings.rtx_payload_type == -1) {
1792 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 1851 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX "
1793 "payload type. Ignoring."; 1852 "payload type. Ignoring.";
1794 parameters_.config.rtp.rtx.ssrcs.clear(); 1853 parameters_.config.rtp.rtx.ssrcs.clear();
1795 } else { 1854 } else {
1796 parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 1855 parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type;
1797 } 1856 }
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
2153 // Call stream_->Start() if necessary conditions are met. 2212 // Call stream_->Start() if necessary conditions are met.
2154 UpdateSendState(); 2213 UpdateSendState();
2155 } 2214 }
2156 2215
2157 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 2216 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
2158 webrtc::Call* call, 2217 webrtc::Call* call,
2159 const StreamParams& sp, 2218 const StreamParams& sp,
2160 webrtc::VideoReceiveStream::Config config, 2219 webrtc::VideoReceiveStream::Config config,
2161 WebRtcVideoDecoderFactory* external_decoder_factory, 2220 WebRtcVideoDecoderFactory* external_decoder_factory,
2162 bool default_stream, 2221 bool default_stream,
2163 const std::vector<VideoCodecSettings>& recv_codecs) 2222 const std::vector<VideoCodecSettings>& recv_codecs,
2223 webrtc::FlexfecConfig flexfec_config)
magjed_webrtc 2016/11/17 13:37:19 Make this const-ref instead of by-value.
brandtr 2016/11/17 17:28:58 Done.
2164 : call_(call), 2224 : call_(call),
2165 stream_params_(sp), 2225 stream_params_(sp),
2166 stream_(NULL), 2226 stream_(NULL),
2167 default_stream_(default_stream), 2227 default_stream_(default_stream),
2168 config_(std::move(config)), 2228 config_(std::move(config)),
2229 flexfec_config_(flexfec_config),
2230 flexfec_stream_(nullptr),
2169 external_decoder_factory_(external_decoder_factory), 2231 external_decoder_factory_(external_decoder_factory),
2170 sink_(NULL), 2232 sink_(NULL),
2171 first_frame_timestamp_(-1), 2233 first_frame_timestamp_(-1),
2172 estimated_remote_start_ntp_time_ms_(0) { 2234 estimated_remote_start_ntp_time_ms_(0) {
2173 config_.renderer = this; 2235 config_.renderer = this;
2174 std::vector<AllocatedDecoder> old_decoders; 2236 std::vector<AllocatedDecoder> old_decoders;
2175 ConfigureCodecs(recv_codecs, &old_decoders); 2237 ConfigureCodecs(recv_codecs, &old_decoders);
2176 RecreateWebRtcStream(); 2238 RecreateWebRtcStream();
2177 RTC_DCHECK(old_decoders.empty()); 2239 RTC_DCHECK(old_decoders.empty());
2178 } 2240 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2287 webrtc::VideoReceiveStream::Decoder decoder; 2349 webrtc::VideoReceiveStream::Decoder decoder;
2288 decoder.decoder = allocated_decoder.decoder; 2350 decoder.decoder = allocated_decoder.decoder;
2289 decoder.payload_type = recv_codecs[i].codec.id; 2351 decoder.payload_type = recv_codecs[i].codec.id;
2290 decoder.payload_name = recv_codecs[i].codec.name; 2352 decoder.payload_name = recv_codecs[i].codec.name;
2291 ConfigureDecoderSpecifics(&decoder, recv_codecs[i].codec); 2353 ConfigureDecoderSpecifics(&decoder, recv_codecs[i].codec);
2292 config_.decoders.push_back(decoder); 2354 config_.decoders.push_back(decoder);
2293 } 2355 }
2294 2356
2295 // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 2357 // TODO(pbos): Reconfigure RTX based on incoming recv_codecs.
2296 config_.rtp.ulpfec = recv_codecs.front().ulpfec; 2358 config_.rtp.ulpfec = recv_codecs.front().ulpfec;
2359 flexfec_config_.flexfec_payload_type =
2360 recv_codecs.front().flexfec.flexfec_payload_type;
2297 config_.rtp.nack.rtp_history_ms = 2361 config_.rtp.nack.rtp_history_ms =
2298 HasNack(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 2362 HasNack(recv_codecs.begin()->codec) ? kNackHistoryMs : 0;
2299 } 2363 }
2300 2364
2301 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetLocalSsrc( 2365 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetLocalSsrc(
2302 uint32_t local_ssrc) { 2366 uint32_t local_ssrc) {
2303 // TODO(pbos): Consider turning this sanity check into a RTC_DCHECK. You 2367 // TODO(pbos): Consider turning this sanity check into a RTC_DCHECK. You
2304 // should not be able to create a sender with the same SSRC as a receiver, but 2368 // should not be able to create a sender with the same SSRC as a receiver, but
2305 // right now this can't be done due to unittests depending on receiving what 2369 // right now this can't be done due to unittests depending on receiving what
2306 // they are sending from the same MediaChannel. 2370 // they are sending from the same MediaChannel.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2358 needs_recreation = true; 2422 needs_recreation = true;
2359 } 2423 }
2360 if (needs_recreation) { 2424 if (needs_recreation) {
2361 LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvParameters"; 2425 LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvParameters";
2362 RecreateWebRtcStream(); 2426 RecreateWebRtcStream();
2363 ClearDecoders(&old_decoders); 2427 ClearDecoders(&old_decoders);
2364 } 2428 }
2365 } 2429 }
2366 2430
2367 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 2431 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() {
2368 if (stream_ != NULL) { 2432 if (flexfec_stream_) {
2433 call_->DestroyFlexfecReceiveStream(flexfec_stream_);
2434 flexfec_stream_ = nullptr;
2435 }
2436 if (stream_) {
2369 call_->DestroyVideoReceiveStream(stream_); 2437 call_->DestroyVideoReceiveStream(stream_);
2370 } 2438 }
2371 stream_ = call_->CreateVideoReceiveStream(config_.Copy()); 2439 stream_ = call_->CreateVideoReceiveStream(config_.Copy());
2372 stream_->Start(); 2440 stream_->Start();
2441 if (IsFlexfecEnabled() && flexfec_config_.IsValid()) {
2442 flexfec_stream_ = call_->CreateFlexfecReceiveStream(flexfec_config_);
2443 flexfec_stream_->Start();
2444 }
2373 } 2445 }
2374 2446
2375 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( 2447 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders(
2376 std::vector<AllocatedDecoder>* allocated_decoders) { 2448 std::vector<AllocatedDecoder>* allocated_decoders) {
2377 for (size_t i = 0; i < allocated_decoders->size(); ++i) { 2449 for (size_t i = 0; i < allocated_decoders->size(); ++i) {
2378 if ((*allocated_decoders)[i].external) { 2450 if ((*allocated_decoders)[i].external) {
2379 external_decoder_factory_->DestroyVideoDecoder( 2451 external_decoder_factory_->DestroyVideoDecoder(
2380 (*allocated_decoders)[i].external_decoder); 2452 (*allocated_decoders)[i].external_decoder);
2381 } 2453 }
2382 delete (*allocated_decoders)[i].decoder; 2454 delete (*allocated_decoders)[i].decoder;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
2481 2553
2482 WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 2554 WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings()
2483 : rtx_payload_type(-1) {} 2555 : rtx_payload_type(-1) {}
2484 2556
2485 bool WebRtcVideoChannel2::VideoCodecSettings::operator==( 2557 bool WebRtcVideoChannel2::VideoCodecSettings::operator==(
2486 const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2558 const WebRtcVideoChannel2::VideoCodecSettings& other) const {
2487 return codec == other.codec && 2559 return codec == other.codec &&
2488 ulpfec.ulpfec_payload_type == other.ulpfec.ulpfec_payload_type && 2560 ulpfec.ulpfec_payload_type == other.ulpfec.ulpfec_payload_type &&
2489 ulpfec.red_payload_type == other.ulpfec.red_payload_type && 2561 ulpfec.red_payload_type == other.ulpfec.red_payload_type &&
2490 ulpfec.red_rtx_payload_type == other.ulpfec.red_rtx_payload_type && 2562 ulpfec.red_rtx_payload_type == other.ulpfec.red_rtx_payload_type &&
2563 flexfec.flexfec_payload_type == other.flexfec.flexfec_payload_type &&
magjed_webrtc 2016/11/17 13:37:19 Maybe you should implement operator== for FlexfecC
brandtr 2016/11/17 17:28:58 Done. Also implemented it for UlpfecConfig, to fur
2564 flexfec.flexfec_ssrc == other.flexfec.flexfec_ssrc &&
2565 flexfec.protected_media_ssrcs == other.flexfec.protected_media_ssrcs &&
2491 rtx_payload_type == other.rtx_payload_type; 2566 rtx_payload_type == other.rtx_payload_type;
2492 } 2567 }
2493 2568
2494 bool WebRtcVideoChannel2::VideoCodecSettings::operator!=( 2569 bool WebRtcVideoChannel2::VideoCodecSettings::operator!=(
2495 const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2570 const WebRtcVideoChannel2::VideoCodecSettings& other) const {
2496 return !(*this == other); 2571 return !(*this == other);
2497 } 2572 }
2498 2573
2499 std::vector<WebRtcVideoChannel2::VideoCodecSettings> 2574 std::vector<WebRtcVideoChannel2::VideoCodecSettings>
2500 WebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 2575 WebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) {
2501 RTC_DCHECK(!codecs.empty()); 2576 RTC_DCHECK(!codecs.empty());
2502 2577
2503 std::vector<VideoCodecSettings> video_codecs; 2578 std::vector<VideoCodecSettings> video_codecs;
2504 std::map<int, bool> payload_used; 2579 std::map<int, bool> payload_used;
2505 std::map<int, VideoCodec::CodecType> payload_codec_type; 2580 std::map<int, VideoCodec::CodecType> payload_codec_type;
2506 // |rtx_mapping| maps video payload type to rtx payload type. 2581 // |rtx_mapping| maps video payload type to rtx payload type.
2507 std::map<int, int> rtx_mapping; 2582 std::map<int, int> rtx_mapping;
2508 2583
2509 webrtc::UlpfecConfig ulpfec_config; 2584 webrtc::UlpfecConfig ulpfec_config;
2585 int flexfec_payload_type = -1;
2510 2586
2511 for (size_t i = 0; i < codecs.size(); ++i) { 2587 for (size_t i = 0; i < codecs.size(); ++i) {
2512 const VideoCodec& in_codec = codecs[i]; 2588 const VideoCodec& in_codec = codecs[i];
2513 int payload_type = in_codec.id; 2589 int payload_type = in_codec.id;
2514 2590
2515 if (payload_used[payload_type]) { 2591 if (payload_used[payload_type]) {
2516 LOG(LS_ERROR) << "Payload type already registered: " 2592 LOG(LS_ERROR) << "Payload type already registered: "
2517 << in_codec.ToString(); 2593 << in_codec.ToString();
2518 return std::vector<VideoCodecSettings>(); 2594 return std::vector<VideoCodecSettings>();
2519 } 2595 }
2520 payload_used[payload_type] = true; 2596 payload_used[payload_type] = true;
2521 payload_codec_type[payload_type] = in_codec.GetCodecType(); 2597 payload_codec_type[payload_type] = in_codec.GetCodecType();
2522 2598
2523 switch (in_codec.GetCodecType()) { 2599 switch (in_codec.GetCodecType()) {
2524 case VideoCodec::CODEC_RED: { 2600 case VideoCodec::CODEC_RED: {
2525 // RED payload type, should not have duplicates. 2601 // RED payload type, should not have duplicates.
2526 RTC_DCHECK(ulpfec_config.red_payload_type == -1); 2602 RTC_DCHECK(ulpfec_config.red_payload_type == -1);
2527 ulpfec_config.red_payload_type = in_codec.id; 2603 ulpfec_config.red_payload_type = in_codec.id;
2528 continue; 2604 continue;
2529 } 2605 }
2530 2606
2531 case VideoCodec::CODEC_ULPFEC: { 2607 case VideoCodec::CODEC_ULPFEC: {
2532 // ULPFEC payload type, should not have duplicates. 2608 // ULPFEC payload type, should not have duplicates.
2533 RTC_DCHECK(ulpfec_config.ulpfec_payload_type == -1); 2609 RTC_DCHECK(ulpfec_config.ulpfec_payload_type == -1);
2534 ulpfec_config.ulpfec_payload_type = in_codec.id; 2610 ulpfec_config.ulpfec_payload_type = in_codec.id;
2535 continue; 2611 continue;
2536 } 2612 }
2537 2613
2538 case VideoCodec::CODEC_FLEXFEC: { 2614 case VideoCodec::CODEC_FLEXFEC: {
2539 // TODO(brandtr): To be implemented. 2615 // FlexFEC payload type, should not have duplicates.
2616 RTC_DCHECK(flexfec_payload_type == -1);
magjed_webrtc 2016/11/17 13:37:19 Use RTC_DCHECK_EQ(-1, flexfec_payload_type) instea
brandtr 2016/11/17 17:28:58 Done.
2617 flexfec_payload_type = in_codec.id;
2540 continue; 2618 continue;
2541 } 2619 }
2542 2620
2543 case VideoCodec::CODEC_RTX: { 2621 case VideoCodec::CODEC_RTX: {
2544 int associated_payload_type; 2622 int associated_payload_type;
2545 if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 2623 if (!in_codec.GetParam(kCodecParamAssociatedPayloadType,
2546 &associated_payload_type) || 2624 &associated_payload_type) ||
2547 !IsValidRtpPayloadType(associated_payload_type)) { 2625 !IsValidRtpPayloadType(associated_payload_type)) {
2548 LOG(LS_ERROR) 2626 LOG(LS_ERROR)
2549 << "RTX codec with invalid or no associated payload type: " 2627 << "RTX codec with invalid or no associated payload type: "
(...skipping 29 matching lines...) Expand all
2579 return std::vector<VideoCodecSettings>(); 2657 return std::vector<VideoCodecSettings>();
2580 } 2658 }
2581 2659
2582 if (it->first == ulpfec_config.red_payload_type) { 2660 if (it->first == ulpfec_config.red_payload_type) {
2583 ulpfec_config.red_rtx_payload_type = it->second; 2661 ulpfec_config.red_rtx_payload_type = it->second;
2584 } 2662 }
2585 } 2663 }
2586 2664
2587 for (size_t i = 0; i < video_codecs.size(); ++i) { 2665 for (size_t i = 0; i < video_codecs.size(); ++i) {
2588 video_codecs[i].ulpfec = ulpfec_config; 2666 video_codecs[i].ulpfec = ulpfec_config;
2667 video_codecs[i].flexfec.flexfec_payload_type = flexfec_payload_type;
2589 if (rtx_mapping[video_codecs[i].codec.id] != 0 && 2668 if (rtx_mapping[video_codecs[i].codec.id] != 0 &&
2590 rtx_mapping[video_codecs[i].codec.id] != 2669 rtx_mapping[video_codecs[i].codec.id] !=
2591 ulpfec_config.red_payload_type) { 2670 ulpfec_config.red_payload_type) {
2592 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2671 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id];
2593 } 2672 }
2594 } 2673 }
2595 2674
2596 return video_codecs; 2675 return video_codecs;
2597 } 2676 }
2598 2677
2599 } // namespace cricket 2678 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698