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 |