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 20 matching lines...) Expand all Loading... |
31 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" | 31 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
32 #include "webrtc/media/engine/webrtcvoiceengine.h" | 32 #include "webrtc/media/engine/webrtcvoiceengine.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/system_wrappers/include/field_trial.h" | 34 #include "webrtc/system_wrappers/include/field_trial.h" |
35 #include "webrtc/video_decoder.h" | 35 #include "webrtc/video_decoder.h" |
36 #include "webrtc/video_encoder.h" | 36 #include "webrtc/video_encoder.h" |
37 | 37 |
38 namespace cricket { | 38 namespace cricket { |
39 namespace { | 39 namespace { |
40 | 40 |
| 41 // Three things happen when the FlexFEC field trial is enabled: |
| 42 // 1) FlexFEC is exposed in the default codec list, eventually showing up |
| 43 // in the default SDP. (See InternalEncoderFactory ctor.) |
| 44 // 2) FlexFEC send parameters are set in the VideoSendStream config. |
| 45 // 3) FlexFEC receive parameters are set in the FlexfecReceiveStream config, |
| 46 // and the corresponding object is instantiated. |
| 47 const char kFlexfecFieldTrialName[] = "WebRTC-FlexFEC-03"; |
| 48 |
| 49 bool IsFlexfecFieldTrialEnabled() { |
| 50 return webrtc::field_trial::FindFullName(kFlexfecFieldTrialName) == "Enabled"; |
| 51 } |
| 52 |
41 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. | 53 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. |
42 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { | 54 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { |
43 public: | 55 public: |
44 // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned | 56 // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned |
45 // by e.g. PeerConnectionFactory. | 57 // by e.g. PeerConnectionFactory. |
46 explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory) | 58 explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory) |
47 : factory_(factory) {} | 59 : factory_(factory) {} |
48 virtual ~EncoderFactoryAdapter() {} | 60 virtual ~EncoderFactoryAdapter() {} |
49 | 61 |
50 // Implement webrtc::VideoEncoderFactory. | 62 // Implement webrtc::VideoEncoderFactory. |
(...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 receive_streams_.erase(prev_stream); | 1201 receive_streams_.erase(prev_stream); |
1190 } | 1202 } |
1191 | 1203 |
1192 if (!ValidateReceiveSsrcAvailability(sp)) | 1204 if (!ValidateReceiveSsrcAvailability(sp)) |
1193 return false; | 1205 return false; |
1194 | 1206 |
1195 for (uint32_t used_ssrc : sp.ssrcs) | 1207 for (uint32_t used_ssrc : sp.ssrcs) |
1196 receive_ssrcs_.insert(used_ssrc); | 1208 receive_ssrcs_.insert(used_ssrc); |
1197 | 1209 |
1198 webrtc::VideoReceiveStream::Config config(this); | 1210 webrtc::VideoReceiveStream::Config config(this); |
1199 ConfigureReceiverRtp(&config, sp); | 1211 webrtc::FlexfecConfig flexfec_config; |
| 1212 ConfigureReceiverRtp(&config, &flexfec_config, sp); |
1200 | 1213 |
1201 // Set up A/V sync group based on sync label. | 1214 // Set up A/V sync group based on sync label. |
1202 config.sync_group = sp.sync_label; | 1215 config.sync_group = sp.sync_label; |
1203 | 1216 |
1204 config.rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false; | 1217 config.rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false; |
1205 config.rtp.transport_cc = | 1218 config.rtp.transport_cc = |
1206 send_codec_ ? HasTransportCc(send_codec_->codec) : false; | 1219 send_codec_ ? HasTransportCc(send_codec_->codec) : false; |
1207 config.disable_prerenderer_smoothing = | 1220 config.disable_prerenderer_smoothing = |
1208 video_config_.disable_prerenderer_smoothing; | 1221 video_config_.disable_prerenderer_smoothing; |
1209 | 1222 |
1210 receive_streams_[ssrc] = new WebRtcVideoReceiveStream( | 1223 receive_streams_[ssrc] = new WebRtcVideoReceiveStream( |
1211 call_, sp, std::move(config), external_decoder_factory_, default_stream, | 1224 call_, sp, std::move(config), external_decoder_factory_, default_stream, |
1212 recv_codecs_); | 1225 recv_codecs_, flexfec_config); |
1213 | 1226 |
1214 return true; | 1227 return true; |
1215 } | 1228 } |
1216 | 1229 |
1217 void WebRtcVideoChannel2::ConfigureReceiverRtp( | 1230 void WebRtcVideoChannel2::ConfigureReceiverRtp( |
1218 webrtc::VideoReceiveStream::Config* config, | 1231 webrtc::VideoReceiveStream::Config* config, |
| 1232 webrtc::FlexfecConfig* flexfec_config, |
1219 const StreamParams& sp) const { | 1233 const StreamParams& sp) const { |
1220 uint32_t ssrc = sp.first_ssrc(); | 1234 uint32_t ssrc = sp.first_ssrc(); |
1221 | 1235 |
1222 config->rtp.remote_ssrc = ssrc; | 1236 config->rtp.remote_ssrc = ssrc; |
1223 config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; | 1237 config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; |
1224 | 1238 |
1225 config->rtp.extensions = recv_rtp_extensions_; | 1239 config->rtp.extensions = recv_rtp_extensions_; |
1226 // Whether or not the receive stream sends reduced size RTCP is determined | 1240 // Whether or not the receive stream sends reduced size RTCP is determined |
1227 // by the send params. | 1241 // by the send params. |
1228 // TODO(deadbeef): Once we change "send_params" to "sender_params" and | 1242 // TODO(deadbeef): Once we change "send_params" to "sender_params" and |
(...skipping 18 matching lines...) Expand all Loading... |
1247 for (size_t i = 0; i < recv_codecs_.size(); ++i) { | 1261 for (size_t i = 0; i < recv_codecs_.size(); ++i) { |
1248 uint32_t rtx_ssrc; | 1262 uint32_t rtx_ssrc; |
1249 if (recv_codecs_[i].rtx_payload_type != -1 && | 1263 if (recv_codecs_[i].rtx_payload_type != -1 && |
1250 sp.GetFidSsrc(ssrc, &rtx_ssrc)) { | 1264 sp.GetFidSsrc(ssrc, &rtx_ssrc)) { |
1251 webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = | 1265 webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = |
1252 config->rtp.rtx[recv_codecs_[i].codec.id]; | 1266 config->rtp.rtx[recv_codecs_[i].codec.id]; |
1253 rtx.ssrc = rtx_ssrc; | 1267 rtx.ssrc = rtx_ssrc; |
1254 rtx.payload_type = recv_codecs_[i].rtx_payload_type; | 1268 rtx.payload_type = recv_codecs_[i].rtx_payload_type; |
1255 } | 1269 } |
1256 } | 1270 } |
| 1271 |
| 1272 // TODO(brandtr): This code needs to be generalized when we add support for |
| 1273 // multistream protection. |
| 1274 uint32_t flexfec_ssrc; |
| 1275 if (sp.GetFecFrSsrc(ssrc, &flexfec_ssrc)) { |
| 1276 flexfec_config->flexfec_ssrc = flexfec_ssrc; |
| 1277 flexfec_config->protected_media_ssrcs = {ssrc}; |
| 1278 } |
1257 } | 1279 } |
1258 | 1280 |
1259 bool WebRtcVideoChannel2::RemoveRecvStream(uint32_t ssrc) { | 1281 bool WebRtcVideoChannel2::RemoveRecvStream(uint32_t ssrc) { |
1260 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; | 1282 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; |
1261 if (ssrc == 0) { | 1283 if (ssrc == 0) { |
1262 LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; | 1284 LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; |
1263 return false; | 1285 return false; |
1264 } | 1286 } |
1265 | 1287 |
1266 rtc::CritScope stream_lock(&stream_crit_); | 1288 rtc::CritScope stream_lock(&stream_crit_); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1404 if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { | 1426 if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { |
1405 return; | 1427 return; |
1406 } | 1428 } |
1407 | 1429 |
1408 int payload_type = 0; | 1430 int payload_type = 0; |
1409 if (!GetRtpPayloadType(packet->cdata(), packet->size(), &payload_type)) { | 1431 if (!GetRtpPayloadType(packet->cdata(), packet->size(), &payload_type)) { |
1410 return; | 1432 return; |
1411 } | 1433 } |
1412 | 1434 |
1413 // See if this payload_type is registered as one that usually gets its own | 1435 // See if this payload_type is registered as one that usually gets its own |
1414 // SSRC (RTX) or at least is safe to drop either way (ULPFEC). If it is, and | 1436 // SSRC (RTX) or at least is safe to drop either way (FEC). If it is, and |
1415 // it wasn't handled above by DeliverPacket, that means we don't know what | 1437 // it wasn't handled above by DeliverPacket, that means we don't know what |
1416 // stream it associates with, and we shouldn't ever create an implicit channel | 1438 // stream it associates with, and we shouldn't ever create an implicit channel |
1417 // for these. | 1439 // for these. |
1418 for (auto& codec : recv_codecs_) { | 1440 for (auto& codec : recv_codecs_) { |
1419 if (payload_type == codec.rtx_payload_type || | 1441 if (payload_type == codec.rtx_payload_type || |
1420 payload_type == codec.ulpfec.red_rtx_payload_type || | 1442 payload_type == codec.ulpfec.red_rtx_payload_type || |
1421 payload_type == codec.ulpfec.ulpfec_payload_type) { | 1443 payload_type == codec.ulpfec.ulpfec_payload_type || |
| 1444 payload_type == codec.flexfec.flexfec_payload_type) { |
1422 return; | 1445 return; |
1423 } | 1446 } |
1424 } | 1447 } |
1425 | 1448 |
1426 switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { | 1449 switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { |
1427 case UnsignalledSsrcHandler::kDropPacket: | 1450 case UnsignalledSsrcHandler::kDropPacket: |
1428 return; | 1451 return; |
1429 case UnsignalledSsrcHandler::kDeliverPacket: | 1452 case UnsignalledSsrcHandler::kDeliverPacket: |
1430 break; | 1453 break; |
1431 } | 1454 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1554 encoder_sink_(nullptr), | 1577 encoder_sink_(nullptr), |
1555 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), | 1578 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), |
1556 rtp_parameters_(CreateRtpParametersWithOneEncoding()), | 1579 rtp_parameters_(CreateRtpParametersWithOneEncoding()), |
1557 allocated_encoder_(nullptr, cricket::VideoCodec(), false), | 1580 allocated_encoder_(nullptr, cricket::VideoCodec(), false), |
1558 sending_(false), | 1581 sending_(false), |
1559 last_frame_timestamp_us_(0) { | 1582 last_frame_timestamp_us_(0) { |
1560 parameters_.config.rtp.max_packet_size = kVideoMtu; | 1583 parameters_.config.rtp.max_packet_size = kVideoMtu; |
1561 parameters_.conference_mode = send_params.conference_mode; | 1584 parameters_.conference_mode = send_params.conference_mode; |
1562 | 1585 |
1563 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); | 1586 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); |
| 1587 |
| 1588 // RTX. |
1564 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, | 1589 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, |
1565 ¶meters_.config.rtp.rtx.ssrcs); | 1590 ¶meters_.config.rtp.rtx.ssrcs); |
| 1591 |
| 1592 // FlexFEC. |
| 1593 // TODO(brandtr): This code needs to be generalized when we add support for |
| 1594 // multistream protection. |
| 1595 if (IsFlexfecFieldTrialEnabled()) { |
| 1596 uint32_t flexfec_ssrc; |
| 1597 bool flexfec_enabled = false; |
| 1598 for (uint32_t primary_ssrc : parameters_.config.rtp.ssrcs) { |
| 1599 if (sp.GetFecFrSsrc(primary_ssrc, &flexfec_ssrc)) { |
| 1600 if (flexfec_enabled) { |
| 1601 LOG(LS_INFO) << "Multiple FlexFEC streams proposed by remote, but " |
| 1602 "our implementation only supports a single FlexFEC " |
| 1603 "stream. Will not enable FlexFEC for proposed " |
| 1604 "stream with SSRC: " |
| 1605 << flexfec_ssrc << "."; |
| 1606 continue; |
| 1607 } |
| 1608 |
| 1609 flexfec_enabled = true; |
| 1610 parameters_.config.rtp.flexfec.flexfec_ssrc = flexfec_ssrc; |
| 1611 parameters_.config.rtp.flexfec.protected_media_ssrcs = {primary_ssrc}; |
| 1612 } |
| 1613 } |
| 1614 } |
| 1615 |
1566 parameters_.config.rtp.c_name = sp.cname; | 1616 parameters_.config.rtp.c_name = sp.cname; |
1567 if (rtp_extensions) { | 1617 if (rtp_extensions) { |
1568 parameters_.config.rtp.extensions = *rtp_extensions; | 1618 parameters_.config.rtp.extensions = *rtp_extensions; |
1569 } | 1619 } |
1570 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size | 1620 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size |
1571 ? webrtc::RtcpMode::kReducedSize | 1621 ? webrtc::RtcpMode::kReducedSize |
1572 : webrtc::RtcpMode::kCompound; | 1622 : webrtc::RtcpMode::kCompound; |
1573 if (codec_settings) { | 1623 if (codec_settings) { |
1574 SetCodec(*codec_settings); | 1624 SetCodec(*codec_settings); |
1575 } | 1625 } |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1736 parameters_.config.encoder_settings.encoder = new_encoder.encoder; | 1786 parameters_.config.encoder_settings.encoder = new_encoder.encoder; |
1737 parameters_.config.encoder_settings.full_overuse_time = new_encoder.external; | 1787 parameters_.config.encoder_settings.full_overuse_time = new_encoder.external; |
1738 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; | 1788 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; |
1739 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; | 1789 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; |
1740 if (new_encoder.external) { | 1790 if (new_encoder.external) { |
1741 webrtc::VideoCodecType type = CodecTypeFromName(codec_settings.codec.name); | 1791 webrtc::VideoCodecType type = CodecTypeFromName(codec_settings.codec.name); |
1742 parameters_.config.encoder_settings.internal_source = | 1792 parameters_.config.encoder_settings.internal_source = |
1743 external_encoder_factory_->EncoderTypeHasInternalSource(type); | 1793 external_encoder_factory_->EncoderTypeHasInternalSource(type); |
1744 } | 1794 } |
1745 parameters_.config.rtp.ulpfec = codec_settings.ulpfec; | 1795 parameters_.config.rtp.ulpfec = codec_settings.ulpfec; |
| 1796 parameters_.config.rtp.flexfec.flexfec_payload_type = |
| 1797 codec_settings.flexfec.flexfec_payload_type; |
1746 | 1798 |
1747 // Set RTX payload type if RTX is enabled. | 1799 // Set RTX payload type if RTX is enabled. |
1748 if (!parameters_.config.rtp.rtx.ssrcs.empty()) { | 1800 if (!parameters_.config.rtp.rtx.ssrcs.empty()) { |
1749 if (codec_settings.rtx_payload_type == -1) { | 1801 if (codec_settings.rtx_payload_type == -1) { |
1750 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " | 1802 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " |
1751 "payload type. Ignoring."; | 1803 "payload type. Ignoring."; |
1752 parameters_.config.rtp.rtx.ssrcs.clear(); | 1804 parameters_.config.rtp.rtx.ssrcs.clear(); |
1753 } else { | 1805 } else { |
1754 parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; | 1806 parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; |
1755 } | 1807 } |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2111 // Call stream_->Start() if necessary conditions are met. | 2163 // Call stream_->Start() if necessary conditions are met. |
2112 UpdateSendState(); | 2164 UpdateSendState(); |
2113 } | 2165 } |
2114 | 2166 |
2115 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( | 2167 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( |
2116 webrtc::Call* call, | 2168 webrtc::Call* call, |
2117 const StreamParams& sp, | 2169 const StreamParams& sp, |
2118 webrtc::VideoReceiveStream::Config config, | 2170 webrtc::VideoReceiveStream::Config config, |
2119 WebRtcVideoDecoderFactory* external_decoder_factory, | 2171 WebRtcVideoDecoderFactory* external_decoder_factory, |
2120 bool default_stream, | 2172 bool default_stream, |
2121 const std::vector<VideoCodecSettings>& recv_codecs) | 2173 const std::vector<VideoCodecSettings>& recv_codecs, |
| 2174 const webrtc::FlexfecConfig& flexfec_config) |
2122 : call_(call), | 2175 : call_(call), |
2123 stream_params_(sp), | 2176 stream_params_(sp), |
2124 stream_(NULL), | 2177 stream_(NULL), |
2125 default_stream_(default_stream), | 2178 default_stream_(default_stream), |
2126 config_(std::move(config)), | 2179 config_(std::move(config)), |
| 2180 flexfec_config_(flexfec_config), |
| 2181 flexfec_stream_(nullptr), |
2127 external_decoder_factory_(external_decoder_factory), | 2182 external_decoder_factory_(external_decoder_factory), |
2128 sink_(NULL), | 2183 sink_(NULL), |
2129 first_frame_timestamp_(-1), | 2184 first_frame_timestamp_(-1), |
2130 estimated_remote_start_ntp_time_ms_(0) { | 2185 estimated_remote_start_ntp_time_ms_(0) { |
2131 config_.renderer = this; | 2186 config_.renderer = this; |
2132 std::vector<AllocatedDecoder> old_decoders; | 2187 std::vector<AllocatedDecoder> old_decoders; |
2133 ConfigureCodecs(recv_codecs, &old_decoders); | 2188 ConfigureCodecs(recv_codecs, &old_decoders); |
2134 RecreateWebRtcStream(); | 2189 RecreateWebRtcStream(); |
2135 RTC_DCHECK(old_decoders.empty()); | 2190 RTC_DCHECK(old_decoders.empty()); |
2136 } | 2191 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2245 webrtc::VideoReceiveStream::Decoder decoder; | 2300 webrtc::VideoReceiveStream::Decoder decoder; |
2246 decoder.decoder = allocated_decoder.decoder; | 2301 decoder.decoder = allocated_decoder.decoder; |
2247 decoder.payload_type = recv_codecs[i].codec.id; | 2302 decoder.payload_type = recv_codecs[i].codec.id; |
2248 decoder.payload_name = recv_codecs[i].codec.name; | 2303 decoder.payload_name = recv_codecs[i].codec.name; |
2249 ConfigureDecoderSpecifics(&decoder, recv_codecs[i].codec); | 2304 ConfigureDecoderSpecifics(&decoder, recv_codecs[i].codec); |
2250 config_.decoders.push_back(decoder); | 2305 config_.decoders.push_back(decoder); |
2251 } | 2306 } |
2252 | 2307 |
2253 // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. | 2308 // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. |
2254 config_.rtp.ulpfec = recv_codecs.front().ulpfec; | 2309 config_.rtp.ulpfec = recv_codecs.front().ulpfec; |
| 2310 flexfec_config_.flexfec_payload_type = |
| 2311 recv_codecs.front().flexfec.flexfec_payload_type; |
2255 config_.rtp.nack.rtp_history_ms = | 2312 config_.rtp.nack.rtp_history_ms = |
2256 HasNack(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; | 2313 HasNack(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; |
2257 } | 2314 } |
2258 | 2315 |
2259 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetLocalSsrc( | 2316 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetLocalSsrc( |
2260 uint32_t local_ssrc) { | 2317 uint32_t local_ssrc) { |
2261 // TODO(pbos): Consider turning this sanity check into a RTC_DCHECK. You | 2318 // TODO(pbos): Consider turning this sanity check into a RTC_DCHECK. You |
2262 // should not be able to create a sender with the same SSRC as a receiver, but | 2319 // should not be able to create a sender with the same SSRC as a receiver, but |
2263 // right now this can't be done due to unittests depending on receiving what | 2320 // right now this can't be done due to unittests depending on receiving what |
2264 // they are sending from the same MediaChannel. | 2321 // they are sending from the same MediaChannel. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2316 needs_recreation = true; | 2373 needs_recreation = true; |
2317 } | 2374 } |
2318 if (needs_recreation) { | 2375 if (needs_recreation) { |
2319 LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvParameters"; | 2376 LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvParameters"; |
2320 RecreateWebRtcStream(); | 2377 RecreateWebRtcStream(); |
2321 ClearDecoders(&old_decoders); | 2378 ClearDecoders(&old_decoders); |
2322 } | 2379 } |
2323 } | 2380 } |
2324 | 2381 |
2325 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { | 2382 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { |
2326 if (stream_ != NULL) { | 2383 if (flexfec_stream_) { |
| 2384 call_->DestroyFlexfecReceiveStream(flexfec_stream_); |
| 2385 flexfec_stream_ = nullptr; |
| 2386 } |
| 2387 if (stream_) { |
2327 call_->DestroyVideoReceiveStream(stream_); | 2388 call_->DestroyVideoReceiveStream(stream_); |
2328 } | 2389 } |
2329 stream_ = call_->CreateVideoReceiveStream(config_.Copy()); | 2390 stream_ = call_->CreateVideoReceiveStream(config_.Copy()); |
2330 stream_->Start(); | 2391 stream_->Start(); |
| 2392 if (IsFlexfecFieldTrialEnabled() && flexfec_config_.IsCompleteAndEnabled()) { |
| 2393 flexfec_stream_ = call_->CreateFlexfecReceiveStream(flexfec_config_); |
| 2394 flexfec_stream_->Start(); |
| 2395 } |
2331 } | 2396 } |
2332 | 2397 |
2333 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( | 2398 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( |
2334 std::vector<AllocatedDecoder>* allocated_decoders) { | 2399 std::vector<AllocatedDecoder>* allocated_decoders) { |
2335 for (size_t i = 0; i < allocated_decoders->size(); ++i) { | 2400 for (size_t i = 0; i < allocated_decoders->size(); ++i) { |
2336 if ((*allocated_decoders)[i].external) { | 2401 if ((*allocated_decoders)[i].external) { |
2337 external_decoder_factory_->DestroyVideoDecoder( | 2402 external_decoder_factory_->DestroyVideoDecoder( |
2338 (*allocated_decoders)[i].external_decoder); | 2403 (*allocated_decoders)[i].external_decoder); |
2339 } | 2404 } |
2340 delete (*allocated_decoders)[i].decoder; | 2405 delete (*allocated_decoders)[i].decoder; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2435 LOG(LS_INFO) << stats.ToString(rtc::TimeMillis()); | 2500 LOG(LS_INFO) << stats.ToString(rtc::TimeMillis()); |
2436 | 2501 |
2437 return info; | 2502 return info; |
2438 } | 2503 } |
2439 | 2504 |
2440 WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() | 2505 WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() |
2441 : rtx_payload_type(-1) {} | 2506 : rtx_payload_type(-1) {} |
2442 | 2507 |
2443 bool WebRtcVideoChannel2::VideoCodecSettings::operator==( | 2508 bool WebRtcVideoChannel2::VideoCodecSettings::operator==( |
2444 const WebRtcVideoChannel2::VideoCodecSettings& other) const { | 2509 const WebRtcVideoChannel2::VideoCodecSettings& other) const { |
2445 return codec == other.codec && | 2510 return codec == other.codec && ulpfec == other.ulpfec && |
2446 ulpfec.ulpfec_payload_type == other.ulpfec.ulpfec_payload_type && | 2511 flexfec == other.flexfec && rtx_payload_type == other.rtx_payload_type; |
2447 ulpfec.red_payload_type == other.ulpfec.red_payload_type && | |
2448 ulpfec.red_rtx_payload_type == other.ulpfec.red_rtx_payload_type && | |
2449 rtx_payload_type == other.rtx_payload_type; | |
2450 } | 2512 } |
2451 | 2513 |
2452 bool WebRtcVideoChannel2::VideoCodecSettings::operator!=( | 2514 bool WebRtcVideoChannel2::VideoCodecSettings::operator!=( |
2453 const WebRtcVideoChannel2::VideoCodecSettings& other) const { | 2515 const WebRtcVideoChannel2::VideoCodecSettings& other) const { |
2454 return !(*this == other); | 2516 return !(*this == other); |
2455 } | 2517 } |
2456 | 2518 |
2457 std::vector<WebRtcVideoChannel2::VideoCodecSettings> | 2519 std::vector<WebRtcVideoChannel2::VideoCodecSettings> |
2458 WebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { | 2520 WebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { |
2459 RTC_DCHECK(!codecs.empty()); | 2521 RTC_DCHECK(!codecs.empty()); |
2460 | 2522 |
2461 std::vector<VideoCodecSettings> video_codecs; | 2523 std::vector<VideoCodecSettings> video_codecs; |
2462 std::map<int, bool> payload_used; | 2524 std::map<int, bool> payload_used; |
2463 std::map<int, VideoCodec::CodecType> payload_codec_type; | 2525 std::map<int, VideoCodec::CodecType> payload_codec_type; |
2464 // |rtx_mapping| maps video payload type to rtx payload type. | 2526 // |rtx_mapping| maps video payload type to rtx payload type. |
2465 std::map<int, int> rtx_mapping; | 2527 std::map<int, int> rtx_mapping; |
2466 | 2528 |
2467 webrtc::UlpfecConfig ulpfec_config; | 2529 webrtc::UlpfecConfig ulpfec_config; |
| 2530 int flexfec_payload_type = -1; |
2468 | 2531 |
2469 for (size_t i = 0; i < codecs.size(); ++i) { | 2532 for (size_t i = 0; i < codecs.size(); ++i) { |
2470 const VideoCodec& in_codec = codecs[i]; | 2533 const VideoCodec& in_codec = codecs[i]; |
2471 int payload_type = in_codec.id; | 2534 int payload_type = in_codec.id; |
2472 | 2535 |
2473 if (payload_used[payload_type]) { | 2536 if (payload_used[payload_type]) { |
2474 LOG(LS_ERROR) << "Payload type already registered: " | 2537 LOG(LS_ERROR) << "Payload type already registered: " |
2475 << in_codec.ToString(); | 2538 << in_codec.ToString(); |
2476 return std::vector<VideoCodecSettings>(); | 2539 return std::vector<VideoCodecSettings>(); |
2477 } | 2540 } |
2478 payload_used[payload_type] = true; | 2541 payload_used[payload_type] = true; |
2479 payload_codec_type[payload_type] = in_codec.GetCodecType(); | 2542 payload_codec_type[payload_type] = in_codec.GetCodecType(); |
2480 | 2543 |
2481 switch (in_codec.GetCodecType()) { | 2544 switch (in_codec.GetCodecType()) { |
2482 case VideoCodec::CODEC_RED: { | 2545 case VideoCodec::CODEC_RED: { |
2483 // RED payload type, should not have duplicates. | 2546 // RED payload type, should not have duplicates. |
2484 RTC_DCHECK(ulpfec_config.red_payload_type == -1); | 2547 RTC_DCHECK_EQ(-1, ulpfec_config.red_payload_type); |
2485 ulpfec_config.red_payload_type = in_codec.id; | 2548 ulpfec_config.red_payload_type = in_codec.id; |
2486 continue; | 2549 continue; |
2487 } | 2550 } |
2488 | 2551 |
2489 case VideoCodec::CODEC_ULPFEC: { | 2552 case VideoCodec::CODEC_ULPFEC: { |
2490 // ULPFEC payload type, should not have duplicates. | 2553 // ULPFEC payload type, should not have duplicates. |
2491 RTC_DCHECK(ulpfec_config.ulpfec_payload_type == -1); | 2554 RTC_DCHECK_EQ(-1, ulpfec_config.ulpfec_payload_type); |
2492 ulpfec_config.ulpfec_payload_type = in_codec.id; | 2555 ulpfec_config.ulpfec_payload_type = in_codec.id; |
2493 continue; | 2556 continue; |
2494 } | 2557 } |
2495 | 2558 |
2496 case VideoCodec::CODEC_FLEXFEC: { | 2559 case VideoCodec::CODEC_FLEXFEC: { |
2497 // TODO(brandtr): To be implemented. | 2560 // FlexFEC payload type, should not have duplicates. |
| 2561 RTC_DCHECK_EQ(-1, flexfec_payload_type); |
| 2562 flexfec_payload_type = in_codec.id; |
2498 continue; | 2563 continue; |
2499 } | 2564 } |
2500 | 2565 |
2501 case VideoCodec::CODEC_RTX: { | 2566 case VideoCodec::CODEC_RTX: { |
2502 int associated_payload_type; | 2567 int associated_payload_type; |
2503 if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, | 2568 if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, |
2504 &associated_payload_type) || | 2569 &associated_payload_type) || |
2505 !IsValidRtpPayloadType(associated_payload_type)) { | 2570 !IsValidRtpPayloadType(associated_payload_type)) { |
2506 LOG(LS_ERROR) | 2571 LOG(LS_ERROR) |
2507 << "RTX codec with invalid or no associated payload type: " | 2572 << "RTX codec with invalid or no associated payload type: " |
(...skipping 29 matching lines...) Expand all Loading... |
2537 return std::vector<VideoCodecSettings>(); | 2602 return std::vector<VideoCodecSettings>(); |
2538 } | 2603 } |
2539 | 2604 |
2540 if (it->first == ulpfec_config.red_payload_type) { | 2605 if (it->first == ulpfec_config.red_payload_type) { |
2541 ulpfec_config.red_rtx_payload_type = it->second; | 2606 ulpfec_config.red_rtx_payload_type = it->second; |
2542 } | 2607 } |
2543 } | 2608 } |
2544 | 2609 |
2545 for (size_t i = 0; i < video_codecs.size(); ++i) { | 2610 for (size_t i = 0; i < video_codecs.size(); ++i) { |
2546 video_codecs[i].ulpfec = ulpfec_config; | 2611 video_codecs[i].ulpfec = ulpfec_config; |
| 2612 video_codecs[i].flexfec.flexfec_payload_type = flexfec_payload_type; |
2547 if (rtx_mapping[video_codecs[i].codec.id] != 0 && | 2613 if (rtx_mapping[video_codecs[i].codec.id] != 0 && |
2548 rtx_mapping[video_codecs[i].codec.id] != | 2614 rtx_mapping[video_codecs[i].codec.id] != |
2549 ulpfec_config.red_payload_type) { | 2615 ulpfec_config.red_payload_type) { |
2550 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; | 2616 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; |
2551 } | 2617 } |
2552 } | 2618 } |
2553 | 2619 |
2554 return video_codecs; | 2620 return video_codecs; |
2555 } | 2621 } |
2556 | 2622 |
2557 } // namespace cricket | 2623 } // namespace cricket |
OLD | NEW |