Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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(¶meters_.config.rtp.ssrcs); | 1631 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); |
| 1632 | |
| 1633 // RTX. | |
| 1602 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, | 1634 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, |
| 1603 ¶meters_.config.rtp.rtx.ssrcs); | 1635 ¶meters_.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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |