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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 AssignUWord32(buffer, pos, sli.SenderSSRC); | 202 AssignUWord32(buffer, pos, sli.SenderSSRC); |
203 AssignUWord32(buffer, pos, sli.MediaSSRC); | 203 AssignUWord32(buffer, pos, sli.MediaSSRC); |
204 | 204 |
205 AssignUWord8(buffer, pos, sli_item.FirstMB >> 5); | 205 AssignUWord8(buffer, pos, sli_item.FirstMB >> 5); |
206 AssignUWord8(buffer, pos, (sli_item.FirstMB << 3) + | 206 AssignUWord8(buffer, pos, (sli_item.FirstMB << 3) + |
207 ((sli_item.NumberOfMB >> 10) & 0x07)); | 207 ((sli_item.NumberOfMB >> 10) & 0x07)); |
208 AssignUWord8(buffer, pos, sli_item.NumberOfMB >> 2); | 208 AssignUWord8(buffer, pos, sli_item.NumberOfMB >> 2); |
209 AssignUWord8(buffer, pos, (sli_item.NumberOfMB << 6) + sli_item.PictureId); | 209 AssignUWord8(buffer, pos, (sli_item.NumberOfMB << 6) + sli_item.PictureId); |
210 } | 210 } |
211 | 211 |
212 // Generic NACK (RFC 4585). | |
213 // | |
214 // FCI: | |
215 // | |
216 // 0 1 2 3 | |
217 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
218 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
219 // | PID | BLP | | |
220 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
221 | |
222 void CreateNack(const RTCPPacketRTPFBNACK& nack, | |
223 const std::vector<RTCPPacketRTPFBNACKItem>& nack_fields, | |
224 size_t start_index, | |
225 size_t end_index, | |
226 uint8_t* buffer, | |
227 size_t* pos) { | |
228 AssignUWord32(buffer, pos, nack.SenderSSRC); | |
229 AssignUWord32(buffer, pos, nack.MediaSSRC); | |
230 for (size_t i = start_index; i < end_index; ++i) { | |
231 const RTCPPacketRTPFBNACKItem& nack_item = nack_fields[i]; | |
232 AssignUWord16(buffer, pos, nack_item.PacketID); | |
233 AssignUWord16(buffer, pos, nack_item.BitMask); | |
234 } | |
235 } | |
236 | |
237 // Reference picture selection indication (RPSI) (RFC 4585). | 212 // Reference picture selection indication (RPSI) (RFC 4585). |
238 // | 213 // |
239 // FCI: | 214 // FCI: |
240 // | 215 // |
241 // 0 1 2 3 | 216 // 0 1 2 3 |
242 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 217 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
243 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 218 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
244 // | PB |0| Payload Type| Native RPSI bit string | | 219 // | PB |0| Payload Type| Native RPSI bit string | |
245 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 220 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
246 // | defined per codec ... | Padding (0) | | 221 // | defined per codec ... | Padding (0) | |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 while (*index + BlockLength() > max_length) { | 565 while (*index + BlockLength() > max_length) { |
591 if (!OnBufferFull(packet, index, callback)) | 566 if (!OnBufferFull(packet, index, callback)) |
592 return false; | 567 return false; |
593 } | 568 } |
594 const uint8_t kFmt = 2; | 569 const uint8_t kFmt = 2; |
595 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); | 570 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
596 CreateSli(sli_, sli_item_, packet, index); | 571 CreateSli(sli_, sli_item_, packet, index); |
597 return true; | 572 return true; |
598 } | 573 } |
599 | 574 |
600 bool Nack::Create(uint8_t* packet, | |
601 size_t* index, | |
602 size_t max_length, | |
603 RtcpPacket::PacketReadyCallback* callback) const { | |
604 assert(!nack_fields_.empty()); | |
605 // If nack list can't fit in packet, try to fragment. | |
606 size_t nack_index = 0; | |
607 do { | |
608 size_t bytes_left_in_buffer = max_length - *index; | |
609 if (bytes_left_in_buffer < kCommonFbFmtLength + 4) { | |
610 if (!OnBufferFull(packet, index, callback)) | |
611 return false; | |
612 continue; | |
613 } | |
614 int64_t num_nack_fields = | |
615 std::min((bytes_left_in_buffer - kCommonFbFmtLength) / 4, | |
616 nack_fields_.size() - nack_index); | |
617 | |
618 const uint8_t kFmt = 1; | |
619 size_t size_bytes = (num_nack_fields * 4) + kCommonFbFmtLength; | |
620 size_t header_length = ((size_bytes + 3) / 4) - 1; // As 32bit words - 1 | |
621 CreateHeader(kFmt, PT_RTPFB, header_length, packet, index); | |
622 CreateNack(nack_, nack_fields_, nack_index, nack_index + num_nack_fields, | |
623 packet, index); | |
624 | |
625 nack_index += num_nack_fields; | |
626 } while (nack_index < nack_fields_.size()); | |
627 | |
628 return true; | |
629 } | |
630 | |
631 size_t Nack::BlockLength() const { | |
632 return (nack_fields_.size() * 4) + kCommonFbFmtLength; | |
633 } | |
634 | |
635 void Nack::WithList(const uint16_t* nack_list, int length) { | |
636 assert(nack_list); | |
637 assert(nack_fields_.empty()); | |
638 int i = 0; | |
639 while (i < length) { | |
640 uint16_t pid = nack_list[i++]; | |
641 // Bitmask specifies losses in any of the 16 packets following the pid. | |
642 uint16_t bitmask = 0; | |
643 while (i < length) { | |
644 int shift = static_cast<uint16_t>(nack_list[i] - pid) - 1; | |
645 if (shift >= 0 && shift <= 15) { | |
646 bitmask |= (1 << shift); | |
647 ++i; | |
648 } else { | |
649 break; | |
650 } | |
651 } | |
652 RTCPUtility::RTCPPacketRTPFBNACKItem item; | |
653 item.PacketID = pid; | |
654 item.BitMask = bitmask; | |
655 nack_fields_.push_back(item); | |
656 } | |
657 } | |
658 | |
659 bool Rpsi::Create(uint8_t* packet, | 575 bool Rpsi::Create(uint8_t* packet, |
660 size_t* index, | 576 size_t* index, |
661 size_t max_length, | 577 size_t max_length, |
662 RtcpPacket::PacketReadyCallback* callback) const { | 578 RtcpPacket::PacketReadyCallback* callback) const { |
663 assert(rpsi_.NumberOfValidBits > 0); | 579 assert(rpsi_.NumberOfValidBits > 0); |
664 while (*index + BlockLength() > max_length) { | 580 while (*index + BlockLength() > max_length) { |
665 if (!OnBufferFull(packet, index, callback)) | 581 if (!OnBufferFull(packet, index, callback)) |
666 return false; | 582 return false; |
667 } | 583 } |
668 const uint8_t kFmt = 3; | 584 const uint8_t kFmt = 3; |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 return length_; | 782 return length_; |
867 } | 783 } |
868 | 784 |
869 void RawPacket::SetLength(size_t length) { | 785 void RawPacket::SetLength(size_t length) { |
870 assert(length <= buffer_length_); | 786 assert(length <= buffer_length_); |
871 length_ = length; | 787 length_ = length; |
872 } | 788 } |
873 | 789 |
874 } // namespace rtcp | 790 } // namespace rtcp |
875 } // namespace webrtc | 791 } // namespace webrtc |
OLD | NEW |