rtx_receive_stream.cc (2788B)
1 /* 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "call/rtx_receive_stream.h" 12 13 14 #include <cstdint> 15 #include <map> 16 #include <utility> 17 18 #include "api/array_view.h" 19 #include "api/sequence_checker.h" 20 #include "call/rtp_packet_sink_interface.h" 21 #include "modules/rtp_rtcp/include/receive_statistics.h" 22 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 23 #include "modules/rtp_rtcp/source/rtp_packet_received.h" 24 #include "rtc_base/logging.h" 25 26 namespace webrtc { 27 28 RtxReceiveStream::RtxReceiveStream( 29 RtpPacketSinkInterface* media_sink, 30 std::map<int, int> associated_payload_types, 31 uint32_t media_ssrc, 32 ReceiveStatistics* rtp_receive_statistics /* = nullptr */) 33 : media_sink_(media_sink), 34 associated_payload_types_(std::move(associated_payload_types)), 35 media_ssrc_(media_ssrc), 36 rtp_receive_statistics_(rtp_receive_statistics) { 37 packet_checker_.Detach(); 38 if (associated_payload_types_.empty()) { 39 RTC_LOG(LS_WARNING) 40 << "RtxReceiveStream created with empty payload type mapping."; 41 } 42 } 43 44 RtxReceiveStream::~RtxReceiveStream() = default; 45 46 void RtxReceiveStream::SetAssociatedPayloadTypes( 47 std::map<int, int> associated_payload_types) { 48 RTC_DCHECK_RUN_ON(&packet_checker_); 49 associated_payload_types_ = std::move(associated_payload_types); 50 } 51 52 void RtxReceiveStream::OnRtpPacket(const RtpPacketReceived& rtx_packet) { 53 RTC_DCHECK_RUN_ON(&packet_checker_); 54 if (rtp_receive_statistics_) { 55 rtp_receive_statistics_->OnRtpPacket(rtx_packet); 56 } 57 ArrayView<const uint8_t> payload = rtx_packet.payload(); 58 59 if (payload.size() < kRtxHeaderSize) { 60 return; 61 } 62 63 auto it = associated_payload_types_.find(rtx_packet.PayloadType()); 64 if (it == associated_payload_types_.end()) { 65 RTC_DLOG(LS_VERBOSE) << "Unknown payload type " 66 << static_cast<int>(rtx_packet.PayloadType()) 67 << " on rtx ssrc " << rtx_packet.Ssrc(); 68 return; 69 } 70 RtpPacketReceived media_packet; 71 media_packet.CopyHeaderFrom(rtx_packet); 72 73 media_packet.SetSsrc(media_ssrc_); 74 media_packet.SetSequenceNumber((payload[0] << 8) + payload[1]); 75 media_packet.SetPayloadType(it->second); 76 media_packet.set_recovered(true); 77 media_packet.set_arrival_time(rtx_packet.arrival_time()); 78 79 // Skip the RTX header. 80 media_packet.SetPayload(payload.subview(kRtxHeaderSize)); 81 82 media_sink_->OnRtpPacket(media_packet); 83 } 84 85 } // namespace webrtc