diff --git a/srt/Packet.cpp b/srt/Packet.cpp index 94da4f58..05050f23 100644 --- a/srt/Packet.cpp +++ b/srt/Packet.cpp @@ -515,7 +515,7 @@ bool NAKPacket::loadFromData(uint8_t *buf, size_t len) { bool NAKPacket::storeToData() { control_type = NAK; sub_type = 0; - size_t cif_size = getCIFSize(); + size_t cif_size = getCIFSize(lost_list); _data = BufferRaw::create(); _data->setCapacity(HEADER_SIZE + cif_size); @@ -544,9 +544,9 @@ bool NAKPacket::storeToData() { return true; } -size_t NAKPacket::getCIFSize() { +size_t NAKPacket::getCIFSize(std::list &lost) { size_t size = 0; - for (auto it : lost_list) { + for (auto it : lost) { if (it.first + 1 == it.second) { size += 4; } else { diff --git a/srt/Packet.hpp b/srt/Packet.hpp index 8710e940..a226b588 100644 --- a/srt/Packet.hpp +++ b/srt/Packet.hpp @@ -275,9 +275,7 @@ public: bool storeToData() override; std::list lost_list; - -private: - size_t getCIFSize(); + static size_t getCIFSize(std::list &lost); }; /* diff --git a/srt/PacketQueue.cpp b/srt/PacketQueue.cpp index 87f078d6..37980ae0 100644 --- a/srt/PacketQueue.cpp +++ b/srt/PacketQueue.cpp @@ -243,6 +243,7 @@ PacketRecvQueue::PacketRecvQueue(uint32_t max_size, uint32_t init_seq, uint32_t , _pkt_expected_seq(init_seq) , _pkt_buf(max_size) {} bool PacketRecvQueue::inputPacket(DataPacket::Ptr pkt, std::list &out) { + // TraceL << dump() << " seq:" << pkt->packet_seq_number; while (_size > 0 && _start == _end) { if (_pkt_buf[_start]) { out.push_back(_pkt_buf[_start]); @@ -385,6 +386,8 @@ std::string PacketRecvQueue::dump() { << " first:" << getFirst()->packet_seq_number; printer << " last:" << getLast()->packet_seq_number; printer << " latency:" << timeLatency() / 1e3; + printer << " start:" << _start; + printer << " end:" << _end; } return std::move(printer); } @@ -438,8 +441,20 @@ void PacketRecvQueue::insertToCycleBuf(DataPacket::Ptr pkt, uint32_t diff) { return; } _pkt_buf[pos] = pkt; - if (pos >= _end && (_start <= _end || pos < _start)) { + + if (_start <= _end && pos >= _end) { _end = (pos + 1) % _pkt_cap; + return; + } + + if (_start <= _end && pos < _start) { + _end = (pos + 1) % _pkt_cap; + return; + } + + if (_start > _end && _end <= pos && _start > pos) { + _end = (pos + 1) % _pkt_cap; + return; } } void PacketRecvQueue::tryInsertPkt(DataPacket::Ptr pkt) { diff --git a/srt/SrtTransport.cpp b/srt/SrtTransport.cpp index ba90b8ab..52ecc449 100644 --- a/srt/SrtTransport.cpp +++ b/srt/SrtTransport.cpp @@ -1,4 +1,5 @@ #include "Util/onceToken.h" +#include #include #include "Ack.hpp" @@ -435,15 +436,42 @@ void SrtTransport::sendLightACKPacket() { void SrtTransport::sendNAKPacket(std::list &lost_list) { NAKPacket::Ptr pkt = std::make_shared(); + std::list tmp; + auto size = NAKPacket::getCIFSize(lost_list); + size_t paylaod_size = getPayloadSize(); + if (size > paylaod_size) { + WarnL << "loss report cif size " << size; + size_t num = paylaod_size / 8; - pkt->dst_socket_id = _peer_socket_id; - pkt->timestamp = DurationCountMicroseconds(_now - _start_timestamp); - pkt->lost_list = lost_list; + size_t msgNum = (lost_list.size() + num - 1) / num; + decltype(lost_list.begin()) cur, next; + for (size_t i = 0; i < msgNum; ++i) { + cur = lost_list.begin(); + std::advance(cur, i * num); - pkt->storeToData(); + if (i == msgNum - 1) { + next = lost_list.end(); + } else { + next = lost_list.begin(); + std::advance(next, (i + 1) * num); + } + tmp.assign(cur, next); + pkt->dst_socket_id = _peer_socket_id; + pkt->timestamp = DurationCountMicroseconds(_now - _start_timestamp); + pkt->lost_list = tmp; + pkt->storeToData(); + sendControlPacket(pkt, true); + } + + } else { + pkt->dst_socket_id = _peer_socket_id; + pkt->timestamp = DurationCountMicroseconds(_now - _start_timestamp); + pkt->lost_list = lost_list; + pkt->storeToData(); + sendControlPacket(pkt, true); + } // TraceL<<"send NAK "<dump(); - sendControlPacket(pkt, true); } void SrtTransport::sendShutDown() {