| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2  *  Copyright (c) 2016 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 30 matching lines...) Expand all  Loading... | 
| 41       last_recovered_packet_ms_(-1) { | 41       last_recovered_packet_ms_(-1) { | 
| 42   // It's OK to create this object on a different thread/task queue than | 42   // It's OK to create this object on a different thread/task queue than | 
| 43   // the one used during main operation. | 43   // the one used during main operation. | 
| 44   sequence_checker_.Detach(); | 44   sequence_checker_.Detach(); | 
| 45 } | 45 } | 
| 46 | 46 | 
| 47 FlexfecReceiver::~FlexfecReceiver() = default; | 47 FlexfecReceiver::~FlexfecReceiver() = default; | 
| 48 | 48 | 
| 49 void FlexfecReceiver::OnRtpPacket(const RtpPacketReceived& packet) { | 49 void FlexfecReceiver::OnRtpPacket(const RtpPacketReceived& packet) { | 
| 50   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | 50   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | 
| 51   if (!AddReceivedPacket(packet)) { | 51   std::unique_ptr<ReceivedPacket> received_packet = AddReceivedPacket(packet); | 
|  | 52   if (!received_packet) | 
| 52     return; | 53     return; | 
| 53   } | 54 | 
| 54   ProcessReceivedPackets(); | 55   ProcessReceivedPacket(*received_packet); | 
| 55 } | 56 } | 
| 56 | 57 | 
| 57 FecPacketCounter FlexfecReceiver::GetPacketCounter() const { | 58 FecPacketCounter FlexfecReceiver::GetPacketCounter() const { | 
| 58   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | 59   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | 
| 59   return packet_counter_; | 60   return packet_counter_; | 
| 60 } | 61 } | 
| 61 | 62 | 
| 62 // TODO(eladalon): Consider using packet.recovered() to avoid processing | 63 // TODO(eladalon): Consider using packet.recovered() to avoid processing | 
| 63 // recovered packets here. | 64 // recovered packets here. | 
| 64 bool FlexfecReceiver::AddReceivedPacket(const RtpPacketReceived& packet) { | 65 std::unique_ptr<ReceivedPacket> FlexfecReceiver::AddReceivedPacket( | 
|  | 66     const RtpPacketReceived& packet) { | 
| 65   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | 67   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | 
| 66 | 68 | 
| 67   // RTP packets with a full base header (12 bytes), but without payload, | 69   // RTP packets with a full base header (12 bytes), but without payload, | 
| 68   // could conceivably be useful in the decoding. Therefore we check | 70   // could conceivably be useful in the decoding. Therefore we check | 
| 69   // with a non-strict inequality here. | 71   // with a non-strict inequality here. | 
| 70   RTC_DCHECK_GE(packet.size(), kRtpHeaderSize); | 72   RTC_DCHECK_GE(packet.size(), kRtpHeaderSize); | 
| 71 | 73 | 
| 72   // Demultiplex based on SSRC, and insert into erasure code decoder. | 74   // Demultiplex based on SSRC, and insert into erasure code decoder. | 
| 73   std::unique_ptr<ReceivedPacket> received_packet(new ReceivedPacket()); | 75   std::unique_ptr<ReceivedPacket> received_packet(new ReceivedPacket()); | 
| 74   received_packet->seq_num = packet.SequenceNumber(); | 76   received_packet->seq_num = packet.SequenceNumber(); | 
| 75   received_packet->ssrc = packet.Ssrc(); | 77   received_packet->ssrc = packet.Ssrc(); | 
| 76   if (received_packet->ssrc == ssrc_) { | 78   if (received_packet->ssrc == ssrc_) { | 
| 77     // This is a FlexFEC packet. | 79     // This is a FlexFEC packet. | 
| 78     if (packet.payload_size() < kMinFlexfecHeaderSize) { | 80     if (packet.payload_size() < kMinFlexfecHeaderSize) { | 
| 79       LOG(LS_WARNING) << "Truncated FlexFEC packet, discarding."; | 81       LOG(LS_WARNING) << "Truncated FlexFEC packet, discarding."; | 
| 80       return false; | 82       return nullptr; | 
| 81     } | 83     } | 
| 82     received_packet->is_fec = true; | 84     received_packet->is_fec = true; | 
| 83     ++packet_counter_.num_fec_packets; | 85     ++packet_counter_.num_fec_packets; | 
| 84 | 86 | 
| 85     // Insert packet payload into erasure code. | 87     // Insert packet payload into erasure code. | 
| 86     // TODO(brandtr): Remove this memcpy when the FEC packet classes | 88     // TODO(brandtr): Remove this memcpy when the FEC packet classes | 
| 87     // are using COW buffers internally. | 89     // are using COW buffers internally. | 
| 88     received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet()); | 90     received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet()); | 
| 89     auto payload = packet.payload(); | 91     auto payload = packet.payload(); | 
| 90     memcpy(received_packet->pkt->data, payload.data(), payload.size()); | 92     memcpy(received_packet->pkt->data, payload.data(), payload.size()); | 
| 91     received_packet->pkt->length = payload.size(); | 93     received_packet->pkt->length = payload.size(); | 
| 92   } else { | 94   } else { | 
| 93     // This is a media packet, or a FlexFEC packet belonging to some | 95     // This is a media packet, or a FlexFEC packet belonging to some | 
| 94     // other FlexFEC stream. | 96     // other FlexFEC stream. | 
| 95     if (received_packet->ssrc != protected_media_ssrc_) { | 97     if (received_packet->ssrc != protected_media_ssrc_) { | 
| 96       return false; | 98       return nullptr; | 
| 97     } | 99     } | 
| 98     received_packet->is_fec = false; | 100     received_packet->is_fec = false; | 
| 99 | 101 | 
| 100     // Insert entire packet into erasure code. | 102     // Insert entire packet into erasure code. | 
| 101     // TODO(brandtr): Remove this memcpy too. | 103     // TODO(brandtr): Remove this memcpy too. | 
| 102     received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet()); | 104     received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet()); | 
| 103     memcpy(received_packet->pkt->data, packet.data(), packet.size()); | 105     memcpy(received_packet->pkt->data, packet.data(), packet.size()); | 
| 104     received_packet->pkt->length = packet.size(); | 106     received_packet->pkt->length = packet.size(); | 
| 105   } | 107   } | 
| 106 | 108 | 
| 107   received_packets_.push_back(std::move(received_packet)); |  | 
| 108   ++packet_counter_.num_packets; | 109   ++packet_counter_.num_packets; | 
| 109 | 110 | 
| 110   return true; | 111   return received_packet; | 
| 111 } | 112 } | 
| 112 | 113 | 
| 113 // Note that the implementation of this member function and the implementation | 114 // Note that the implementation of this member function and the implementation | 
| 114 // in UlpfecReceiver::ProcessReceivedFec() are slightly different. | 115 // in UlpfecReceiver::ProcessReceivedFec() are slightly different. | 
| 115 // This implementation only returns _recovered_ media packets through the | 116 // This implementation only returns _recovered_ media packets through the | 
| 116 // callback, whereas the implementation in UlpfecReceiver returns _all inserted_ | 117 // callback, whereas the implementation in UlpfecReceiver returns _all inserted_ | 
| 117 // media packets through the callback. The latter behaviour makes sense | 118 // media packets through the callback. The latter behaviour makes sense | 
| 118 // for ULPFEC, since the ULPFEC receiver is owned by the RtpVideoStreamReceiver. | 119 // for ULPFEC, since the ULPFEC receiver is owned by the RtpVideoStreamReceiver. | 
| 119 // Here, however, the received media pipeline is more decoupled from the | 120 // Here, however, the received media pipeline is more decoupled from the | 
| 120 // FlexFEC decoder, and we therefore do not interfere with the reception | 121 // FlexFEC decoder, and we therefore do not interfere with the reception | 
| 121 // of non-recovered media packets. | 122 // of non-recovered media packets. | 
| 122 bool FlexfecReceiver::ProcessReceivedPackets() { | 123 void FlexfecReceiver::ProcessReceivedPacket( | 
|  | 124     const ReceivedPacket& received_packet) { | 
| 123   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | 125   RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | 
| 124 | 126 | 
| 125   // Decode. | 127   // Decode. | 
| 126   if (!received_packets_.empty()) { | 128   erasure_code_->DecodeFec(received_packet, &recovered_packets_); | 
| 127     if (erasure_code_->DecodeFec(&received_packets_, &recovered_packets_) != | 129 | 
| 128         0) { |  | 
| 129       return false; |  | 
| 130     } |  | 
| 131   } |  | 
| 132   // Return recovered packets through callback. | 130   // Return recovered packets through callback. | 
| 133   for (const auto& recovered_packet : recovered_packets_) { | 131   for (const auto& recovered_packet : recovered_packets_) { | 
| 134     if (recovered_packet->returned) { | 132     if (recovered_packet->returned) { | 
| 135       continue; | 133       continue; | 
| 136     } | 134     } | 
| 137     ++packet_counter_.num_recovered_packets; | 135     ++packet_counter_.num_recovered_packets; | 
| 138     // Set this flag first, since OnRecoveredPacket may end up here | 136     // Set this flag first, since OnRecoveredPacket may end up here | 
| 139     // again, with the same packet. | 137     // again, with the same packet. | 
| 140     recovered_packet->returned = true; | 138     recovered_packet->returned = true; | 
| 141     recovered_packet_receiver_->OnRecoveredPacket( | 139     recovered_packet_receiver_->OnRecoveredPacket( | 
| 142         recovered_packet->pkt->data, recovered_packet->pkt->length); | 140         recovered_packet->pkt->data, recovered_packet->pkt->length); | 
| 143     // Periodically log the incoming packets. | 141     // Periodically log the incoming packets. | 
| 144     int64_t now_ms = clock_->TimeInMilliseconds(); | 142     int64_t now_ms = clock_->TimeInMilliseconds(); | 
| 145     if (now_ms - last_recovered_packet_ms_ > kPacketLogIntervalMs) { | 143     if (now_ms - last_recovered_packet_ms_ > kPacketLogIntervalMs) { | 
| 146       uint32_t media_ssrc = | 144       uint32_t media_ssrc = | 
| 147           ForwardErrorCorrection::ParseSsrc(recovered_packet->pkt->data); | 145           ForwardErrorCorrection::ParseSsrc(recovered_packet->pkt->data); | 
| 148       LOG(LS_VERBOSE) << "Recovered media packet with SSRC: " << media_ssrc | 146       LOG(LS_VERBOSE) << "Recovered media packet with SSRC: " << media_ssrc | 
| 149                       << " from FlexFEC stream with SSRC: " << ssrc_ << "."; | 147                       << " from FlexFEC stream with SSRC: " << ssrc_ << "."; | 
| 150       last_recovered_packet_ms_ = now_ms; | 148       last_recovered_packet_ms_ = now_ms; | 
| 151     } | 149     } | 
| 152   } | 150   } | 
| 153   return true; |  | 
| 154 } | 151 } | 
| 155 | 152 | 
| 156 }  // namespace webrtc | 153 }  // namespace webrtc | 
| OLD | NEW | 
|---|