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 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
863 "codec or RTCP mode has changed."; | 863 "codec or RTCP mode has changed."; |
864 for (auto& kv : receive_streams_) { | 864 for (auto& kv : receive_streams_) { |
865 RTC_DCHECK(kv.second != nullptr); | 865 RTC_DCHECK(kv.second != nullptr); |
866 kv.second->SetFeedbackParameters( | 866 kv.second->SetFeedbackParameters( |
867 HasNack(send_codec_->codec), HasRemb(send_codec_->codec), | 867 HasNack(send_codec_->codec), HasRemb(send_codec_->codec), |
868 HasTransportCc(send_codec_->codec), | 868 HasTransportCc(send_codec_->codec), |
869 params.rtcp.reduced_size ? webrtc::RtcpMode::kReducedSize | 869 params.rtcp.reduced_size ? webrtc::RtcpMode::kReducedSize |
870 : webrtc::RtcpMode::kCompound); | 870 : webrtc::RtcpMode::kCompound); |
871 } | 871 } |
872 } | 872 } |
873 if (changed_params.codec) { | |
874 if (changed_params.codec->fec.red_payload_type == -1) { | |
875 red_enabled_remote_peer_ = rtc::Optional<bool>(false); | |
876 LOG(LS_ERROR) << "Codec changed to not have RED. Recv streams: " | |
877 << receive_streams_.size() << " " << this; | |
878 for (auto& kv : receive_streams_) { | |
879 // In practice VideoChannel::SetRemoteContent appears to most of the | |
880 // time also call UpdateRemoteStreams, which recreates the receive | |
881 // streams. If that's always true this call isn't needed. | |
882 kv.second->DisableFec(); | |
883 } | |
884 } else { | |
885 red_enabled_remote_peer_ = rtc::Optional<bool>(true); | |
886 } | |
887 } | |
873 } | 888 } |
874 send_params_ = params; | 889 send_params_ = params; |
875 return true; | 890 return true; |
876 } | 891 } |
877 | 892 |
878 webrtc::RtpParameters WebRtcVideoChannel2::GetRtpParameters( | 893 webrtc::RtpParameters WebRtcVideoChannel2::GetRtpParameters( |
879 uint32_t ssrc) const { | 894 uint32_t ssrc) const { |
880 rtc::CritScope stream_lock(&stream_crit_); | 895 rtc::CritScope stream_lock(&stream_crit_); |
881 auto it = send_streams_.find(ssrc); | 896 auto it = send_streams_.find(ssrc); |
882 if (it == send_streams_.end()) { | 897 if (it == send_streams_.end()) { |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1141 } | 1156 } |
1142 | 1157 |
1143 bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { | 1158 bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { |
1144 return AddRecvStream(sp, false); | 1159 return AddRecvStream(sp, false); |
1145 } | 1160 } |
1146 | 1161 |
1147 bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp, | 1162 bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp, |
1148 bool default_stream) { | 1163 bool default_stream) { |
1149 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1164 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1150 | 1165 |
1151 LOG(LS_INFO) << "AddRecvStream" << (default_stream ? " (default stream)" : "") | 1166 LOG(LS_WARNING) << "AddRecvStream" |
pbos-webrtc
2016/05/09 19:57:01
INFO
stefan-webrtc
2016/05/16 08:49:55
Done.
| |
1152 << ": " << sp.ToString(); | 1167 << (default_stream ? " (default stream)" : "") << ": " |
1168 << sp.ToString(); | |
1153 if (!ValidateStreamParams(sp)) | 1169 if (!ValidateStreamParams(sp)) |
1154 return false; | 1170 return false; |
1155 | 1171 |
1156 uint32_t ssrc = sp.first_ssrc(); | 1172 uint32_t ssrc = sp.first_ssrc(); |
1157 RTC_DCHECK(ssrc != 0); // TODO(pbos): Is this ever valid? | 1173 RTC_DCHECK(ssrc != 0); // TODO(pbos): Is this ever valid? |
1158 | 1174 |
1159 rtc::CritScope stream_lock(&stream_crit_); | 1175 rtc::CritScope stream_lock(&stream_crit_); |
1160 // Remove running stream if this was a default stream. | 1176 // Remove running stream if this was a default stream. |
1161 const auto& prev_stream = receive_streams_.find(ssrc); | 1177 const auto& prev_stream = receive_streams_.find(ssrc); |
1162 if (prev_stream != receive_streams_.end()) { | 1178 if (prev_stream != receive_streams_.end()) { |
(...skipping 26 matching lines...) Expand all Loading... | |
1189 | 1205 |
1190 receive_streams_[ssrc] = new WebRtcVideoReceiveStream( | 1206 receive_streams_[ssrc] = new WebRtcVideoReceiveStream( |
1191 call_, sp, config, external_decoder_factory_, default_stream, | 1207 call_, sp, config, external_decoder_factory_, default_stream, |
1192 recv_codecs_); | 1208 recv_codecs_); |
1193 | 1209 |
1194 return true; | 1210 return true; |
1195 } | 1211 } |
1196 | 1212 |
1197 void WebRtcVideoChannel2::ConfigureReceiverRtp( | 1213 void WebRtcVideoChannel2::ConfigureReceiverRtp( |
1198 webrtc::VideoReceiveStream::Config* config, | 1214 webrtc::VideoReceiveStream::Config* config, |
1199 const StreamParams& sp) const { | 1215 const StreamParams& sp) { |
1200 uint32_t ssrc = sp.first_ssrc(); | 1216 uint32_t ssrc = sp.first_ssrc(); |
1201 | 1217 |
1202 config->rtp.remote_ssrc = ssrc; | 1218 config->rtp.remote_ssrc = ssrc; |
1203 config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; | 1219 config->rtp.local_ssrc = rtcp_receiver_report_ssrc_; |
1204 | 1220 |
1205 config->rtp.extensions = recv_rtp_extensions_; | 1221 config->rtp.extensions = recv_rtp_extensions_; |
1206 // Whether or not the receive stream sends reduced size RTCP is determined | 1222 // Whether or not the receive stream sends reduced size RTCP is determined |
1207 // by the send params. | 1223 // by the send params. |
1208 // TODO(deadbeef): Once we change "send_params" to "sender_params" and | 1224 // TODO(deadbeef): Once we change "send_params" to "sender_params" and |
1209 // "recv_params" to "receiver_params", we should get this out of | 1225 // "recv_params" to "receiver_params", we should get this out of |
1210 // receiver_params_. | 1226 // receiver_params_. |
1211 config->rtp.rtcp_mode = send_params_.rtcp.reduced_size | 1227 config->rtp.rtcp_mode = send_params_.rtcp.reduced_size |
1212 ? webrtc::RtcpMode::kReducedSize | 1228 ? webrtc::RtcpMode::kReducedSize |
1213 : webrtc::RtcpMode::kCompound; | 1229 : webrtc::RtcpMode::kCompound; |
1214 | 1230 |
1215 // TODO(pbos): This protection is against setting the same local ssrc as | 1231 // TODO(pbos): This protection is against setting the same local ssrc as |
1216 // remote which is not permitted by the lower-level API. RTCP requires a | 1232 // remote which is not permitted by the lower-level API. RTCP requires a |
1217 // corresponding sender SSRC. Figure out what to do when we don't have | 1233 // corresponding sender SSRC. Figure out what to do when we don't have |
1218 // (receive-only) or know a good local SSRC. | 1234 // (receive-only) or know a good local SSRC. |
1219 if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { | 1235 if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { |
1220 if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { | 1236 if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { |
1221 config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; | 1237 config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; |
1222 } else { | 1238 } else { |
1223 config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; | 1239 config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; |
1224 } | 1240 } |
1225 } | 1241 } |
1226 | 1242 |
1227 for (size_t i = 0; i < recv_codecs_.size(); ++i) { | 1243 for (size_t i = 0; i < recv_codecs_.size(); ++i) { |
1228 MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec); | 1244 if (red_enabled_remote_peer_.value_or(true)) { |
1245 LOG(LS_WARNING) << "Remote peer has red " << this; | |
Taylor Brandstetter
2016/05/09 18:40:36
May want to make this log message look nicer (and
pbos-webrtc
2016/05/09 19:57:01
INFO
stefan-webrtc
2016/05/16 08:49:55
Done.
| |
1246 | |
1247 // TODO(holmer): Why is this merged if WebRtcVideoReceiveStream anyway | |
1248 // uses recv_codecs_ to set up FEC, and then overwrites its config_? | |
1249 MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec); | |
Taylor Brandstetter
2016/05/09 18:40:36
If this is actually completely redundant, you migh
stefan-webrtc
2016/05/16 08:49:55
Done.
| |
1250 } else { | |
1251 LOG(LS_WARNING) << "Remote peer doesn't have red " << this; | |
pbos-webrtc
2016/05/09 19:57:00
INFO
stefan-webrtc
2016/05/16 08:49:55
Done.
| |
1252 config->rtp.fec.red_payload_type = -1; | |
1253 config->rtp.fec.ulpfec_payload_type = -1; | |
Taylor Brandstetter
2016/05/09 18:40:36
Dumb question, but it possible to use ulpfec witho
stefan-webrtc
2016/05/16 08:49:55
In theory, maybe, but we don't support it.
| |
1254 config->rtp.fec.red_rtx_payload_type = -1; | |
1255 recv_codecs_[i].fec.red_payload_type = -1; | |
1256 recv_codecs_[i].fec.ulpfec_payload_type = -1; | |
1257 recv_codecs_[i].fec.red_rtx_payload_type = -1; | |
1258 } | |
1229 } | 1259 } |
1230 | 1260 |
1231 for (size_t i = 0; i < recv_codecs_.size(); ++i) { | 1261 for (size_t i = 0; i < recv_codecs_.size(); ++i) { |
1232 uint32_t rtx_ssrc; | 1262 uint32_t rtx_ssrc; |
1233 if (recv_codecs_[i].rtx_payload_type != -1 && | 1263 if (recv_codecs_[i].rtx_payload_type != -1 && |
1234 sp.GetFidSsrc(ssrc, &rtx_ssrc)) { | 1264 sp.GetFidSsrc(ssrc, &rtx_ssrc)) { |
1235 webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = | 1265 webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = |
1236 config->rtp.rtx[recv_codecs_[i].codec.id]; | 1266 config->rtp.rtx[recv_codecs_[i].codec.id]; |
1237 rtx.ssrc = rtx_ssrc; | 1267 rtx.ssrc = rtx_ssrc; |
1238 rtx.payload_type = recv_codecs_[i].rtx_payload_type; | 1268 rtx.payload_type = recv_codecs_[i].rtx_payload_type; |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1458 // due to lack of socket buffer space, although it's not yet clear what the | 1488 // due to lack of socket buffer space, although it's not yet clear what the |
1459 // ideal value should be. | 1489 // ideal value should be. |
1460 MediaChannel::SetOption(NetworkInterface::ST_RTP, | 1490 MediaChannel::SetOption(NetworkInterface::ST_RTP, |
1461 rtc::Socket::OPT_SNDBUF, | 1491 rtc::Socket::OPT_SNDBUF, |
1462 kVideoRtpBufferSize); | 1492 kVideoRtpBufferSize); |
1463 } | 1493 } |
1464 | 1494 |
1465 bool WebRtcVideoChannel2::SendRtp(const uint8_t* data, | 1495 bool WebRtcVideoChannel2::SendRtp(const uint8_t* data, |
1466 size_t len, | 1496 size_t len, |
1467 const webrtc::PacketOptions& options) { | 1497 const webrtc::PacketOptions& options) { |
1498 static int i = 0; | |
pbos-webrtc
2016/05/09 19:57:00
don't commit this ;p
stefan-webrtc
2016/05/16 08:49:55
Acknowledged.
| |
1499 if (i++ % 100 == 5) | |
1500 return true; | |
Taylor Brandstetter
2016/05/09 18:40:36
Remember to remove this before submitting
stefan-webrtc
2016/05/16 08:49:55
Acknowledged.
| |
1468 rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen); | 1501 rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen); |
1469 rtc::PacketOptions rtc_options; | 1502 rtc::PacketOptions rtc_options; |
1470 rtc_options.packet_id = options.packet_id; | 1503 rtc_options.packet_id = options.packet_id; |
1471 return MediaChannel::SendPacket(&packet, rtc_options); | 1504 return MediaChannel::SendPacket(&packet, rtc_options); |
1472 } | 1505 } |
1473 | 1506 |
1474 bool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { | 1507 bool WebRtcVideoChannel2::SendRtcp(const uint8_t* data, size_t len) { |
1475 rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen); | 1508 rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen); |
1476 return MediaChannel::SendRtcp(&packet, rtc::PacketOptions()); | 1509 return MediaChannel::SendRtcp(&packet, rtc::PacketOptions()); |
1477 } | 1510 } |
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2473 | 2506 |
2474 info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type); | 2507 info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type); |
2475 | 2508 |
2476 info.firs_sent = stats.rtcp_packet_type_counts.fir_packets; | 2509 info.firs_sent = stats.rtcp_packet_type_counts.fir_packets; |
2477 info.plis_sent = stats.rtcp_packet_type_counts.pli_packets; | 2510 info.plis_sent = stats.rtcp_packet_type_counts.pli_packets; |
2478 info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets; | 2511 info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets; |
2479 | 2512 |
2480 return info; | 2513 return info; |
2481 } | 2514 } |
2482 | 2515 |
2516 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::DisableFec() { | |
pbos-webrtc
2016/05/09 19:57:01
Can you re-enable FEC after this change by negotia
| |
2517 stream_->DisableFec(); | |
pbos-webrtc
2016/05/09 19:57:01
I think this method should instead recreate the st
| |
2518 } | |
stefan-webrtc
2016/05/09 13:32:44
Will be removed
| |
2519 | |
2483 WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() | 2520 WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() |
2484 : rtx_payload_type(-1) {} | 2521 : rtx_payload_type(-1) {} |
2485 | 2522 |
2486 bool WebRtcVideoChannel2::VideoCodecSettings::operator==( | 2523 bool WebRtcVideoChannel2::VideoCodecSettings::operator==( |
2487 const WebRtcVideoChannel2::VideoCodecSettings& other) const { | 2524 const WebRtcVideoChannel2::VideoCodecSettings& other) const { |
2488 return codec == other.codec && | 2525 return codec == other.codec && |
2489 fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && | 2526 fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && |
2490 fec.red_payload_type == other.fec.red_payload_type && | 2527 fec.red_payload_type == other.fec.red_payload_type && |
2491 fec.red_rtx_payload_type == other.fec.red_rtx_payload_type && | 2528 fec.red_rtx_payload_type == other.fec.red_rtx_payload_type && |
2492 rtx_payload_type == other.rtx_payload_type; | 2529 rtx_payload_type == other.rtx_payload_type; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2559 } | 2596 } |
2560 | 2597 |
2561 // One of these codecs should have been a video codec. Only having FEC | 2598 // One of these codecs should have been a video codec. Only having FEC |
2562 // parameters into this code is a logic error. | 2599 // parameters into this code is a logic error. |
2563 RTC_DCHECK(!video_codecs.empty()); | 2600 RTC_DCHECK(!video_codecs.empty()); |
2564 | 2601 |
2565 for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); | 2602 for (std::map<int, int>::const_iterator it = rtx_mapping.begin(); |
2566 it != rtx_mapping.end(); | 2603 it != rtx_mapping.end(); |
2567 ++it) { | 2604 ++it) { |
2568 if (!payload_used[it->first]) { | 2605 if (!payload_used[it->first]) { |
2569 LOG(LS_ERROR) << "RTX mapped to payload not in codec list."; | 2606 LOG(LS_ERROR) << "RTX mapped to payload not in codec list " << it->first; |
2570 return std::vector<VideoCodecSettings>(); | 2607 return std::vector<VideoCodecSettings>(); |
2571 } | 2608 } |
2572 if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO && | 2609 if (payload_codec_type[it->first] != VideoCodec::CODEC_VIDEO && |
2573 payload_codec_type[it->first] != VideoCodec::CODEC_RED) { | 2610 payload_codec_type[it->first] != VideoCodec::CODEC_RED) { |
2574 LOG(LS_ERROR) << "RTX not mapped to regular video codec or RED codec."; | 2611 LOG(LS_ERROR) << "RTX not mapped to regular video codec or RED codec."; |
2575 return std::vector<VideoCodecSettings>(); | 2612 return std::vector<VideoCodecSettings>(); |
2576 } | 2613 } |
2577 | 2614 |
2578 if (it->first == fec_settings.red_payload_type) { | 2615 if (it->first == fec_settings.red_payload_type) { |
2579 fec_settings.red_rtx_payload_type = it->second; | 2616 fec_settings.red_rtx_payload_type = it->second; |
2580 } | 2617 } |
2581 } | 2618 } |
2582 | 2619 |
2583 for (size_t i = 0; i < video_codecs.size(); ++i) { | 2620 for (size_t i = 0; i < video_codecs.size(); ++i) { |
2584 video_codecs[i].fec = fec_settings; | 2621 video_codecs[i].fec = fec_settings; |
2585 if (rtx_mapping[video_codecs[i].codec.id] != 0 && | 2622 if (rtx_mapping[video_codecs[i].codec.id] != 0 && |
2586 rtx_mapping[video_codecs[i].codec.id] != | 2623 rtx_mapping[video_codecs[i].codec.id] != |
2587 fec_settings.red_payload_type) { | 2624 fec_settings.red_payload_type) { |
2588 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; | 2625 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; |
2589 } | 2626 } |
2590 } | 2627 } |
2591 | 2628 |
2592 return video_codecs; | 2629 return video_codecs; |
2593 } | 2630 } |
2594 | 2631 |
2595 } // namespace cricket | 2632 } // namespace cricket |
OLD | NEW |