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

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

Issue 2511703002: Wire up FlexFEC in VideoEngine2. (Closed)
Patch Set: Rebase on top of magjed's CL + corresponding fixes. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 20 matching lines...) Expand all
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.
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 IsFlexfecEnabled() {
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 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 AppendVideoCodecs(internal_codecs, &unified_codecs); 644 AppendVideoCodecs(internal_codecs, &unified_codecs);
633 645
634 if (external_encoder_factory != nullptr) { 646 if (external_encoder_factory != nullptr) {
635 const std::vector<VideoCodec>& external_codecs = 647 const std::vector<VideoCodec>& external_codecs =
636 external_encoder_factory->supported_codecs(); 648 external_encoder_factory->supported_codecs();
637 AppendVideoCodecs(external_codecs, &unified_codecs); 649 AppendVideoCodecs(external_codecs, &unified_codecs);
638 LOG(LS_INFO) << "Codecs supported by the external encoder factory: " 650 LOG(LS_INFO) << "Codecs supported by the external encoder factory: "
639 << CodecVectorToString(external_codecs); 651 << CodecVectorToString(external_codecs);
640 } 652 }
641 653
654 // TODO(brandtr): Move this block of code to InternalEncoderFactory ctor
655 // when FlexFEC is no longer behind a field trial. Until then, we need
656 // to have this block here, since the singleton encoder factory does
657 // not respect the ScopedFieldTrials that we use in the tests.
brandtr 2016/11/17 17:28:58 magjed: Is this OK? Further, checking the field t
magjed_webrtc 2016/11/18 14:28:00 This won't work because the payload won't be assig
brandtr 2016/11/21 08:52:03 I see, moving to the ctor. (Thanks for changing yo
658 if (IsFlexfecEnabled()) {
659 cricket::VideoCodec flexfec_codec(kFlexfecCodecName);
660 // This value is currently arbitrarily set to 10 seconds. (The unit
661 // is microseconds.) This parameter MUST be present in the SDP, but
662 // we never use the actual value anywhere in our code however.
663 // TODO(brandtr): Consider honouring this value in the sender and receiver.
664 flexfec_codec.SetParam(kFlexfecFmtpRepairWindow, "10000000");
665 unified_codecs.push_back(flexfec_codec);
666 LOG(LS_INFO) << "Codec added by field trial: " << flexfec_codec.ToString();
667 }
668
642 return unified_codecs; 669 return unified_codecs;
643 } 670 }
644 671
645 WebRtcVideoChannel2::WebRtcVideoChannel2( 672 WebRtcVideoChannel2::WebRtcVideoChannel2(
646 webrtc::Call* call, 673 webrtc::Call* call,
647 const MediaConfig& config, 674 const MediaConfig& config,
648 const VideoOptions& options, 675 const VideoOptions& options,
649 WebRtcVideoEncoderFactory* external_encoder_factory, 676 WebRtcVideoEncoderFactory* external_encoder_factory,
650 WebRtcVideoDecoderFactory* external_decoder_factory) 677 WebRtcVideoDecoderFactory* external_decoder_factory)
651 : VideoMediaChannel(config), 678 : VideoMediaChannel(config),
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 receive_streams_.erase(prev_stream); 1216 receive_streams_.erase(prev_stream);
1190 } 1217 }
1191 1218
1192 if (!ValidateReceiveSsrcAvailability(sp)) 1219 if (!ValidateReceiveSsrcAvailability(sp))
1193 return false; 1220 return false;
1194 1221
1195 for (uint32_t used_ssrc : sp.ssrcs) 1222 for (uint32_t used_ssrc : sp.ssrcs)
1196 receive_ssrcs_.insert(used_ssrc); 1223 receive_ssrcs_.insert(used_ssrc);
1197 1224
1198 webrtc::VideoReceiveStream::Config config(this); 1225 webrtc::VideoReceiveStream::Config config(this);
1199 ConfigureReceiverRtp(&config, sp); 1226 webrtc::FlexfecConfig flexfec_config;
1227 ConfigureReceiverRtp(&config, &flexfec_config, sp);
1200 1228
1201 // Set up A/V sync group based on sync label. 1229 // Set up A/V sync group based on sync label.
1202 config.sync_group = sp.sync_label; 1230 config.sync_group = sp.sync_label;
1203 1231
1204 config.rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false; 1232 config.rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false;
1205 config.rtp.transport_cc = 1233 config.rtp.transport_cc =
1206 send_codec_ ? HasTransportCc(send_codec_->codec) : false; 1234 send_codec_ ? HasTransportCc(send_codec_->codec) : false;
1207 config.disable_prerenderer_smoothing = 1235 config.disable_prerenderer_smoothing =
1208 video_config_.disable_prerenderer_smoothing; 1236 video_config_.disable_prerenderer_smoothing;
1209 1237
1210 receive_streams_[ssrc] = new WebRtcVideoReceiveStream( 1238 receive_streams_[ssrc] = new WebRtcVideoReceiveStream(
1211 call_, sp, std::move(config), external_decoder_factory_, default_stream, 1239 call_, sp, std::move(config), external_decoder_factory_, default_stream,
1212 recv_codecs_); 1240 recv_codecs_, flexfec_config);
1213 1241
1214 return true; 1242 return true;
1215 } 1243 }
1216 1244
1217 void WebRtcVideoChannel2::ConfigureReceiverRtp( 1245 void WebRtcVideoChannel2::ConfigureReceiverRtp(
1218 webrtc::VideoReceiveStream::Config* config, 1246 webrtc::VideoReceiveStream::Config* config,
1247 webrtc::FlexfecConfig* flexfec_config,
1219 const StreamParams& sp) const { 1248 const StreamParams& sp) const {
1220 uint32_t ssrc = sp.first_ssrc(); 1249 uint32_t ssrc = sp.first_ssrc();
1221 1250
1222 config->rtp.remote_ssrc = ssrc; 1251 config->rtp.remote_ssrc = ssrc;
1223 config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; 1252 config->rtp.local_ssrc = rtcp_receiver_report_ssrc_;
1224 1253
1225 config->rtp.extensions = recv_rtp_extensions_; 1254 config->rtp.extensions = recv_rtp_extensions_;
1226 // Whether or not the receive stream sends reduced size RTCP is determined 1255 // Whether or not the receive stream sends reduced size RTCP is determined
1227 // by the send params. 1256 // by the send params.
1228 // TODO(deadbeef): Once we change "send_params" to "sender_params" and 1257 // TODO(deadbeef): Once we change "send_params" to "sender_params" and
(...skipping 18 matching lines...) Expand all
1247 for (size_t i = 0; i < recv_codecs_.size(); ++i) { 1276 for (size_t i = 0; i < recv_codecs_.size(); ++i) {
1248 uint32_t rtx_ssrc; 1277 uint32_t rtx_ssrc;
1249 if (recv_codecs_[i].rtx_payload_type != -1 && 1278 if (recv_codecs_[i].rtx_payload_type != -1 &&
1250 sp.GetFidSsrc(ssrc, &rtx_ssrc)) { 1279 sp.GetFidSsrc(ssrc, &rtx_ssrc)) {
1251 webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = 1280 webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx =
1252 config->rtp.rtx[recv_codecs_[i].codec.id]; 1281 config->rtp.rtx[recv_codecs_[i].codec.id];
1253 rtx.ssrc = rtx_ssrc; 1282 rtx.ssrc = rtx_ssrc;
1254 rtx.payload_type = recv_codecs_[i].rtx_payload_type; 1283 rtx.payload_type = recv_codecs_[i].rtx_payload_type;
1255 } 1284 }
1256 } 1285 }
1286
1287 // TODO(brandtr): This code needs to be generalized when we add support for
1288 // multistream protection.
1289 uint32_t flexfec_ssrc;
1290 if (sp.GetFecFrSsrc(ssrc, &flexfec_ssrc)) {
1291 flexfec_config->flexfec_ssrc = flexfec_ssrc;
1292 flexfec_config->protected_media_ssrcs = {ssrc};
1293 }
1257 } 1294 }
1258 1295
1259 bool WebRtcVideoChannel2::RemoveRecvStream(uint32_t ssrc) { 1296 bool WebRtcVideoChannel2::RemoveRecvStream(uint32_t ssrc) {
1260 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 1297 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc;
1261 if (ssrc == 0) { 1298 if (ssrc == 0) {
1262 LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported."; 1299 LOG(LS_ERROR) << "RemoveRecvStream with 0 ssrc is not supported.";
1263 return false; 1300 return false;
1264 } 1301 }
1265 1302
1266 rtc::CritScope stream_lock(&stream_crit_); 1303 rtc::CritScope stream_lock(&stream_crit_);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1404 if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) { 1441 if (!GetRtpSsrc(packet->cdata(), packet->size(), &ssrc)) {
1405 return; 1442 return;
1406 } 1443 }
1407 1444
1408 int payload_type = 0; 1445 int payload_type = 0;
1409 if (!GetRtpPayloadType(packet->cdata(), packet->size(), &payload_type)) { 1446 if (!GetRtpPayloadType(packet->cdata(), packet->size(), &payload_type)) {
1410 return; 1447 return;
1411 } 1448 }
1412 1449
1413 // See if this payload_type is registered as one that usually gets its own 1450 // 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 1451 // 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 1452 // 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 1453 // stream it associates with, and we shouldn't ever create an implicit channel
1417 // for these. 1454 // for these.
1418 for (auto& codec : recv_codecs_) { 1455 for (auto& codec : recv_codecs_) {
1419 if (payload_type == codec.rtx_payload_type || 1456 if (payload_type == codec.rtx_payload_type ||
1420 payload_type == codec.ulpfec.red_rtx_payload_type || 1457 payload_type == codec.ulpfec.red_rtx_payload_type ||
1421 payload_type == codec.ulpfec.ulpfec_payload_type) { 1458 payload_type == codec.ulpfec.ulpfec_payload_type ||
1459 payload_type == codec.flexfec.flexfec_payload_type) {
1422 return; 1460 return;
1423 } 1461 }
1424 } 1462 }
1425 1463
1426 switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) { 1464 switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) {
1427 case UnsignalledSsrcHandler::kDropPacket: 1465 case UnsignalledSsrcHandler::kDropPacket:
1428 return; 1466 return;
1429 case UnsignalledSsrcHandler::kDeliverPacket: 1467 case UnsignalledSsrcHandler::kDeliverPacket:
1430 break; 1468 break;
1431 } 1469 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 encoder_sink_(nullptr), 1592 encoder_sink_(nullptr),
1555 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), 1593 parameters_(std::move(config), options, max_bitrate_bps, codec_settings),
1556 rtp_parameters_(CreateRtpParametersWithOneEncoding()), 1594 rtp_parameters_(CreateRtpParametersWithOneEncoding()),
1557 allocated_encoder_(nullptr, cricket::VideoCodec(), false), 1595 allocated_encoder_(nullptr, cricket::VideoCodec(), false),
1558 sending_(false), 1596 sending_(false),
1559 last_frame_timestamp_us_(0) { 1597 last_frame_timestamp_us_(0) {
1560 parameters_.config.rtp.max_packet_size = kVideoMtu; 1598 parameters_.config.rtp.max_packet_size = kVideoMtu;
1561 parameters_.conference_mode = send_params.conference_mode; 1599 parameters_.conference_mode = send_params.conference_mode;
1562 1600
1563 sp.GetPrimarySsrcs(&parameters_.config.rtp.ssrcs); 1601 sp.GetPrimarySsrcs(&parameters_.config.rtp.ssrcs);
1602
1603 // RTX.
1564 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 1604 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs,
1565 &parameters_.config.rtp.rtx.ssrcs); 1605 &parameters_.config.rtp.rtx.ssrcs);
1606
1607 // FlexFEC.
1608 // TODO(brandtr): This code needs to be generalized when we add support for
1609 // multistream protection.
1610 if (IsFlexfecEnabled()) {
1611 uint32_t flexfec_ssrc;
1612 bool flexfec_enabled = false;
1613 for (uint32_t primary_ssrc : parameters_.config.rtp.ssrcs) {
1614 if (sp.GetFecFrSsrc(primary_ssrc, &flexfec_ssrc)) {
1615 if (flexfec_enabled) {
1616 LOG(LS_INFO) << "Multiple FlexFEC streams proposed by remote, but "
1617 "our implementation only supports a single FlexFEC "
1618 "stream. Will not enable FlexFEC for proposed "
1619 "stream with SSRC: "
1620 << flexfec_ssrc << ".";
1621 continue;
1622 }
1623
1624 flexfec_enabled = true;
1625 parameters_.config.rtp.flexfec.flexfec_ssrc = flexfec_ssrc;
1626 parameters_.config.rtp.flexfec.protected_media_ssrcs = {primary_ssrc};
1627 }
1628 }
1629 }
1630
1566 parameters_.config.rtp.c_name = sp.cname; 1631 parameters_.config.rtp.c_name = sp.cname;
1567 if (rtp_extensions) { 1632 if (rtp_extensions) {
1568 parameters_.config.rtp.extensions = *rtp_extensions; 1633 parameters_.config.rtp.extensions = *rtp_extensions;
1569 } 1634 }
1570 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size 1635 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size
1571 ? webrtc::RtcpMode::kReducedSize 1636 ? webrtc::RtcpMode::kReducedSize
1572 : webrtc::RtcpMode::kCompound; 1637 : webrtc::RtcpMode::kCompound;
1573 if (codec_settings) { 1638 if (codec_settings) {
1574 SetCodec(*codec_settings); 1639 SetCodec(*codec_settings);
1575 } 1640 }
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1737 parameters_.config.encoder_settings.encoder = new_encoder.encoder; 1802 parameters_.config.encoder_settings.encoder = new_encoder.encoder;
1738 parameters_.config.encoder_settings.full_overuse_time = new_encoder.external; 1803 parameters_.config.encoder_settings.full_overuse_time = new_encoder.external;
1739 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 1804 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name;
1740 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 1805 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id;
1741 if (new_encoder.external) { 1806 if (new_encoder.external) {
1742 webrtc::VideoCodecType type = CodecTypeFromName(codec_settings.codec.name); 1807 webrtc::VideoCodecType type = CodecTypeFromName(codec_settings.codec.name);
1743 parameters_.config.encoder_settings.internal_source = 1808 parameters_.config.encoder_settings.internal_source =
1744 external_encoder_factory_->EncoderTypeHasInternalSource(type); 1809 external_encoder_factory_->EncoderTypeHasInternalSource(type);
1745 } 1810 }
1746 parameters_.config.rtp.ulpfec = codec_settings.ulpfec; 1811 parameters_.config.rtp.ulpfec = codec_settings.ulpfec;
1812 parameters_.config.rtp.flexfec.flexfec_payload_type =
1813 codec_settings.flexfec.flexfec_payload_type;
1747 1814
1748 // Set RTX payload type if RTX is enabled. 1815 // Set RTX payload type if RTX is enabled.
1749 if (!parameters_.config.rtp.rtx.ssrcs.empty()) { 1816 if (!parameters_.config.rtp.rtx.ssrcs.empty()) {
1750 if (codec_settings.rtx_payload_type == -1) { 1817 if (codec_settings.rtx_payload_type == -1) {
1751 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 1818 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX "
1752 "payload type. Ignoring."; 1819 "payload type. Ignoring.";
1753 parameters_.config.rtp.rtx.ssrcs.clear(); 1820 parameters_.config.rtp.rtx.ssrcs.clear();
1754 } else { 1821 } else {
1755 parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; 1822 parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type;
1756 } 1823 }
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
2112 // Call stream_->Start() if necessary conditions are met. 2179 // Call stream_->Start() if necessary conditions are met.
2113 UpdateSendState(); 2180 UpdateSendState();
2114 } 2181 }
2115 2182
2116 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 2183 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
2117 webrtc::Call* call, 2184 webrtc::Call* call,
2118 const StreamParams& sp, 2185 const StreamParams& sp,
2119 webrtc::VideoReceiveStream::Config config, 2186 webrtc::VideoReceiveStream::Config config,
2120 WebRtcVideoDecoderFactory* external_decoder_factory, 2187 WebRtcVideoDecoderFactory* external_decoder_factory,
2121 bool default_stream, 2188 bool default_stream,
2122 const std::vector<VideoCodecSettings>& recv_codecs) 2189 const std::vector<VideoCodecSettings>& recv_codecs,
2190 const webrtc::FlexfecConfig& flexfec_config)
2123 : call_(call), 2191 : call_(call),
2124 stream_params_(sp), 2192 stream_params_(sp),
2125 stream_(NULL), 2193 stream_(NULL),
2126 default_stream_(default_stream), 2194 default_stream_(default_stream),
2127 config_(std::move(config)), 2195 config_(std::move(config)),
2196 flexfec_config_(flexfec_config),
2197 flexfec_stream_(nullptr),
2128 external_decoder_factory_(external_decoder_factory), 2198 external_decoder_factory_(external_decoder_factory),
2129 sink_(NULL), 2199 sink_(NULL),
2130 first_frame_timestamp_(-1), 2200 first_frame_timestamp_(-1),
2131 estimated_remote_start_ntp_time_ms_(0) { 2201 estimated_remote_start_ntp_time_ms_(0) {
2132 config_.renderer = this; 2202 config_.renderer = this;
2133 std::vector<AllocatedDecoder> old_decoders; 2203 std::vector<AllocatedDecoder> old_decoders;
2134 ConfigureCodecs(recv_codecs, &old_decoders); 2204 ConfigureCodecs(recv_codecs, &old_decoders);
2135 RecreateWebRtcStream(); 2205 RecreateWebRtcStream();
2136 RTC_DCHECK(old_decoders.empty()); 2206 RTC_DCHECK(old_decoders.empty());
2137 } 2207 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2246 webrtc::VideoReceiveStream::Decoder decoder; 2316 webrtc::VideoReceiveStream::Decoder decoder;
2247 decoder.decoder = allocated_decoder.decoder; 2317 decoder.decoder = allocated_decoder.decoder;
2248 decoder.payload_type = recv_codecs[i].codec.id; 2318 decoder.payload_type = recv_codecs[i].codec.id;
2249 decoder.payload_name = recv_codecs[i].codec.name; 2319 decoder.payload_name = recv_codecs[i].codec.name;
2250 ConfigureDecoderSpecifics(&decoder, recv_codecs[i].codec); 2320 ConfigureDecoderSpecifics(&decoder, recv_codecs[i].codec);
2251 config_.decoders.push_back(decoder); 2321 config_.decoders.push_back(decoder);
2252 } 2322 }
2253 2323
2254 // TODO(pbos): Reconfigure RTX based on incoming recv_codecs. 2324 // TODO(pbos): Reconfigure RTX based on incoming recv_codecs.
2255 config_.rtp.ulpfec = recv_codecs.front().ulpfec; 2325 config_.rtp.ulpfec = recv_codecs.front().ulpfec;
2326 flexfec_config_.flexfec_payload_type =
2327 recv_codecs.front().flexfec.flexfec_payload_type;
2256 config_.rtp.nack.rtp_history_ms = 2328 config_.rtp.nack.rtp_history_ms =
2257 HasNack(recv_codecs.begin()->codec) ? kNackHistoryMs : 0; 2329 HasNack(recv_codecs.begin()->codec) ? kNackHistoryMs : 0;
2258 } 2330 }
2259 2331
2260 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetLocalSsrc( 2332 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetLocalSsrc(
2261 uint32_t local_ssrc) { 2333 uint32_t local_ssrc) {
2262 // TODO(pbos): Consider turning this sanity check into a RTC_DCHECK. You 2334 // TODO(pbos): Consider turning this sanity check into a RTC_DCHECK. You
2263 // should not be able to create a sender with the same SSRC as a receiver, but 2335 // should not be able to create a sender with the same SSRC as a receiver, but
2264 // right now this can't be done due to unittests depending on receiving what 2336 // right now this can't be done due to unittests depending on receiving what
2265 // they are sending from the same MediaChannel. 2337 // they are sending from the same MediaChannel.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2317 needs_recreation = true; 2389 needs_recreation = true;
2318 } 2390 }
2319 if (needs_recreation) { 2391 if (needs_recreation) {
2320 LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvParameters"; 2392 LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvParameters";
2321 RecreateWebRtcStream(); 2393 RecreateWebRtcStream();
2322 ClearDecoders(&old_decoders); 2394 ClearDecoders(&old_decoders);
2323 } 2395 }
2324 } 2396 }
2325 2397
2326 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { 2398 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() {
2327 if (stream_ != NULL) { 2399 if (flexfec_stream_) {
2400 call_->DestroyFlexfecReceiveStream(flexfec_stream_);
2401 flexfec_stream_ = nullptr;
2402 }
2403 if (stream_) {
2328 call_->DestroyVideoReceiveStream(stream_); 2404 call_->DestroyVideoReceiveStream(stream_);
2329 } 2405 }
2330 stream_ = call_->CreateVideoReceiveStream(config_.Copy()); 2406 stream_ = call_->CreateVideoReceiveStream(config_.Copy());
2331 stream_->Start(); 2407 stream_->Start();
2408 if (IsFlexfecEnabled() && flexfec_config_.IsCompleteAndEnabled()) {
2409 flexfec_stream_ = call_->CreateFlexfecReceiveStream(flexfec_config_);
2410 flexfec_stream_->Start();
2411 }
2332 } 2412 }
2333 2413
2334 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( 2414 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders(
2335 std::vector<AllocatedDecoder>* allocated_decoders) { 2415 std::vector<AllocatedDecoder>* allocated_decoders) {
2336 for (size_t i = 0; i < allocated_decoders->size(); ++i) { 2416 for (size_t i = 0; i < allocated_decoders->size(); ++i) {
2337 if ((*allocated_decoders)[i].external) { 2417 if ((*allocated_decoders)[i].external) {
2338 external_decoder_factory_->DestroyVideoDecoder( 2418 external_decoder_factory_->DestroyVideoDecoder(
2339 (*allocated_decoders)[i].external_decoder); 2419 (*allocated_decoders)[i].external_decoder);
2340 } 2420 }
2341 delete (*allocated_decoders)[i].decoder; 2421 delete (*allocated_decoders)[i].decoder;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2436 LOG(LS_INFO) << stats.ToString(rtc::TimeMillis()); 2516 LOG(LS_INFO) << stats.ToString(rtc::TimeMillis());
2437 2517
2438 return info; 2518 return info;
2439 } 2519 }
2440 2520
2441 WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() 2521 WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings()
2442 : rtx_payload_type(-1) {} 2522 : rtx_payload_type(-1) {}
2443 2523
2444 bool WebRtcVideoChannel2::VideoCodecSettings::operator==( 2524 bool WebRtcVideoChannel2::VideoCodecSettings::operator==(
2445 const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2525 const WebRtcVideoChannel2::VideoCodecSettings& other) const {
2446 return codec == other.codec && 2526 return codec == other.codec && ulpfec == other.ulpfec &&
2447 ulpfec.ulpfec_payload_type == other.ulpfec.ulpfec_payload_type && 2527 flexfec == other.flexfec && rtx_payload_type == other.rtx_payload_type;
2448 ulpfec.red_payload_type == other.ulpfec.red_payload_type &&
2449 ulpfec.red_rtx_payload_type == other.ulpfec.red_rtx_payload_type &&
2450 rtx_payload_type == other.rtx_payload_type;
2451 } 2528 }
2452 2529
2453 bool WebRtcVideoChannel2::VideoCodecSettings::operator!=( 2530 bool WebRtcVideoChannel2::VideoCodecSettings::operator!=(
2454 const WebRtcVideoChannel2::VideoCodecSettings& other) const { 2531 const WebRtcVideoChannel2::VideoCodecSettings& other) const {
2455 return !(*this == other); 2532 return !(*this == other);
2456 } 2533 }
2457 2534
2458 std::vector<WebRtcVideoChannel2::VideoCodecSettings> 2535 std::vector<WebRtcVideoChannel2::VideoCodecSettings>
2459 WebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) { 2536 WebRtcVideoChannel2::MapCodecs(const std::vector<VideoCodec>& codecs) {
2460 RTC_DCHECK(!codecs.empty()); 2537 RTC_DCHECK(!codecs.empty());
2461 2538
2462 std::vector<VideoCodecSettings> video_codecs; 2539 std::vector<VideoCodecSettings> video_codecs;
2463 std::map<int, bool> payload_used; 2540 std::map<int, bool> payload_used;
2464 std::map<int, VideoCodec::CodecType> payload_codec_type; 2541 std::map<int, VideoCodec::CodecType> payload_codec_type;
2465 // |rtx_mapping| maps video payload type to rtx payload type. 2542 // |rtx_mapping| maps video payload type to rtx payload type.
2466 std::map<int, int> rtx_mapping; 2543 std::map<int, int> rtx_mapping;
2467 2544
2468 webrtc::UlpfecConfig ulpfec_config; 2545 webrtc::UlpfecConfig ulpfec_config;
2546 int flexfec_payload_type = -1;
2469 2547
2470 for (size_t i = 0; i < codecs.size(); ++i) { 2548 for (size_t i = 0; i < codecs.size(); ++i) {
2471 const VideoCodec& in_codec = codecs[i]; 2549 const VideoCodec& in_codec = codecs[i];
2472 int payload_type = in_codec.id; 2550 int payload_type = in_codec.id;
2473 2551
2474 if (payload_used[payload_type]) { 2552 if (payload_used[payload_type]) {
2475 LOG(LS_ERROR) << "Payload type already registered: " 2553 LOG(LS_ERROR) << "Payload type already registered: "
2476 << in_codec.ToString(); 2554 << in_codec.ToString();
2477 return std::vector<VideoCodecSettings>(); 2555 return std::vector<VideoCodecSettings>();
2478 } 2556 }
2479 payload_used[payload_type] = true; 2557 payload_used[payload_type] = true;
2480 payload_codec_type[payload_type] = in_codec.GetCodecType(); 2558 payload_codec_type[payload_type] = in_codec.GetCodecType();
2481 2559
2482 switch (in_codec.GetCodecType()) { 2560 switch (in_codec.GetCodecType()) {
2483 case VideoCodec::CODEC_RED: { 2561 case VideoCodec::CODEC_RED: {
2484 // RED payload type, should not have duplicates. 2562 // RED payload type, should not have duplicates.
2485 RTC_DCHECK(ulpfec_config.red_payload_type == -1); 2563 RTC_DCHECK_EQ(-1, ulpfec_config.red_payload_type);
2486 ulpfec_config.red_payload_type = in_codec.id; 2564 ulpfec_config.red_payload_type = in_codec.id;
2487 continue; 2565 continue;
2488 } 2566 }
2489 2567
2490 case VideoCodec::CODEC_ULPFEC: { 2568 case VideoCodec::CODEC_ULPFEC: {
2491 // ULPFEC payload type, should not have duplicates. 2569 // ULPFEC payload type, should not have duplicates.
2492 RTC_DCHECK(ulpfec_config.ulpfec_payload_type == -1); 2570 RTC_DCHECK_EQ(-1, ulpfec_config.ulpfec_payload_type);
2493 ulpfec_config.ulpfec_payload_type = in_codec.id; 2571 ulpfec_config.ulpfec_payload_type = in_codec.id;
2494 continue; 2572 continue;
2495 } 2573 }
2496 2574
2497 case VideoCodec::CODEC_FLEXFEC: { 2575 case VideoCodec::CODEC_FLEXFEC: {
2498 // TODO(brandtr): To be implemented. 2576 // FlexFEC payload type, should not have duplicates.
2577 RTC_DCHECK_EQ(-1, flexfec_payload_type);
2578 flexfec_payload_type = in_codec.id;
2499 continue; 2579 continue;
2500 } 2580 }
2501 2581
2502 case VideoCodec::CODEC_RTX: { 2582 case VideoCodec::CODEC_RTX: {
2503 int associated_payload_type; 2583 int associated_payload_type;
2504 if (!in_codec.GetParam(kCodecParamAssociatedPayloadType, 2584 if (!in_codec.GetParam(kCodecParamAssociatedPayloadType,
2505 &associated_payload_type) || 2585 &associated_payload_type) ||
2506 !IsValidRtpPayloadType(associated_payload_type)) { 2586 !IsValidRtpPayloadType(associated_payload_type)) {
2507 LOG(LS_ERROR) 2587 LOG(LS_ERROR)
2508 << "RTX codec with invalid or no associated payload type: " 2588 << "RTX codec with invalid or no associated payload type: "
(...skipping 29 matching lines...) Expand all
2538 return std::vector<VideoCodecSettings>(); 2618 return std::vector<VideoCodecSettings>();
2539 } 2619 }
2540 2620
2541 if (it->first == ulpfec_config.red_payload_type) { 2621 if (it->first == ulpfec_config.red_payload_type) {
2542 ulpfec_config.red_rtx_payload_type = it->second; 2622 ulpfec_config.red_rtx_payload_type = it->second;
2543 } 2623 }
2544 } 2624 }
2545 2625
2546 for (size_t i = 0; i < video_codecs.size(); ++i) { 2626 for (size_t i = 0; i < video_codecs.size(); ++i) {
2547 video_codecs[i].ulpfec = ulpfec_config; 2627 video_codecs[i].ulpfec = ulpfec_config;
2628 video_codecs[i].flexfec.flexfec_payload_type = flexfec_payload_type;
2548 if (rtx_mapping[video_codecs[i].codec.id] != 0 && 2629 if (rtx_mapping[video_codecs[i].codec.id] != 0 &&
2549 rtx_mapping[video_codecs[i].codec.id] != 2630 rtx_mapping[video_codecs[i].codec.id] !=
2550 ulpfec_config.red_payload_type) { 2631 ulpfec_config.red_payload_type) {
2551 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2632 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id];
2552 } 2633 }
2553 } 2634 }
2554 2635
2555 return video_codecs; 2636 return video_codecs;
2556 } 2637 }
2557 2638
2558 } // namespace cricket 2639 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698