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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 AssignUWord32(buffer, pos, sli.SenderSSRC); | 272 AssignUWord32(buffer, pos, sli.SenderSSRC); |
273 AssignUWord32(buffer, pos, sli.MediaSSRC); | 273 AssignUWord32(buffer, pos, sli.MediaSSRC); |
274 | 274 |
275 AssignUWord8(buffer, pos, sli_item.FirstMB >> 5); | 275 AssignUWord8(buffer, pos, sli_item.FirstMB >> 5); |
276 AssignUWord8(buffer, pos, (sli_item.FirstMB << 3) + | 276 AssignUWord8(buffer, pos, (sli_item.FirstMB << 3) + |
277 ((sli_item.NumberOfMB >> 10) & 0x07)); | 277 ((sli_item.NumberOfMB >> 10) & 0x07)); |
278 AssignUWord8(buffer, pos, sli_item.NumberOfMB >> 2); | 278 AssignUWord8(buffer, pos, sli_item.NumberOfMB >> 2); |
279 AssignUWord8(buffer, pos, (sli_item.NumberOfMB << 6) + sli_item.PictureId); | 279 AssignUWord8(buffer, pos, (sli_item.NumberOfMB << 6) + sli_item.PictureId); |
280 } | 280 } |
281 | 281 |
282 // Generic NACK (RFC 4585). | |
283 // | |
284 // FCI: | |
285 // | |
286 // 0 1 2 3 | |
287 // 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 | |
288 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
289 // | PID | BLP | | |
290 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
291 | |
292 void CreateNack(const RTCPPacketRTPFBNACK& nack, | |
293 const std::vector<RTCPPacketRTPFBNACKItem>& nack_fields, | |
294 size_t start_index, | |
295 size_t end_index, | |
296 uint8_t* buffer, | |
297 size_t* pos) { | |
298 AssignUWord32(buffer, pos, nack.SenderSSRC); | |
299 AssignUWord32(buffer, pos, nack.MediaSSRC); | |
300 for (size_t i = start_index; i < end_index; ++i) { | |
301 const RTCPPacketRTPFBNACKItem& nack_item = nack_fields[i]; | |
302 AssignUWord16(buffer, pos, nack_item.PacketID); | |
303 AssignUWord16(buffer, pos, nack_item.BitMask); | |
304 } | |
305 } | |
306 | |
307 // Reference picture selection indication (RPSI) (RFC 4585). | 282 // Reference picture selection indication (RPSI) (RFC 4585). |
308 // | 283 // |
309 // FCI: | 284 // FCI: |
310 // | 285 // |
311 // 0 1 2 3 | 286 // 0 1 2 3 |
312 // 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 | 287 // 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 |
313 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 288 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
314 // | PB |0| Payload Type| Native RPSI bit string | | 289 // | PB |0| Payload Type| Native RPSI bit string | |
315 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 290 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
316 // | defined per codec ... | Padding (0) | | 291 // | defined per codec ... | Padding (0) | |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 while (*index + BlockLength() > max_length) { | 820 while (*index + BlockLength() > max_length) { |
846 if (!OnBufferFull(packet, index, callback)) | 821 if (!OnBufferFull(packet, index, callback)) |
847 return false; | 822 return false; |
848 } | 823 } |
849 const uint8_t kFmt = 2; | 824 const uint8_t kFmt = 2; |
850 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); | 825 CreateHeader(kFmt, PT_PSFB, HeaderLength(), packet, index); |
851 CreateSli(sli_, sli_item_, packet, index); | 826 CreateSli(sli_, sli_item_, packet, index); |
852 return true; | 827 return true; |
853 } | 828 } |
854 | 829 |
855 bool Nack::Create(uint8_t* packet, | |
856 size_t* index, | |
857 size_t max_length, | |
858 RtcpPacket::PacketReadyCallback* callback) const { | |
859 assert(!nack_fields_.empty()); | |
860 // If nack list can't fit in packet, try to fragment. | |
861 size_t nack_index = 0; | |
862 do { | |
863 size_t bytes_left_in_buffer = max_length - *index; | |
864 if (bytes_left_in_buffer < kCommonFbFmtLength + 4) { | |
865 if (!OnBufferFull(packet, index, callback)) | |
866 return false; | |
867 continue; | |
868 } | |
869 int64_t num_nack_fields = | |
870 std::min((bytes_left_in_buffer - kCommonFbFmtLength) / 4, | |
871 nack_fields_.size() - nack_index); | |
872 | |
873 const uint8_t kFmt = 1; | |
874 size_t size_bytes = (num_nack_fields * 4) + kCommonFbFmtLength; | |
875 size_t header_length = ((size_bytes + 3) / 4) - 1; // As 32bit words - 1 | |
876 CreateHeader(kFmt, PT_RTPFB, header_length, packet, index); | |
877 CreateNack(nack_, nack_fields_, nack_index, nack_index + num_nack_fields, | |
878 packet, index); | |
879 | |
880 nack_index += num_nack_fields; | |
881 } while (nack_index < nack_fields_.size()); | |
882 | |
883 return true; | |
884 } | |
885 | |
886 size_t Nack::BlockLength() const { | |
887 return (nack_fields_.size() * 4) + kCommonFbFmtLength; | |
888 } | |
889 | |
890 void Nack::WithList(const uint16_t* nack_list, int length) { | |
891 assert(nack_list); | |
892 assert(nack_fields_.empty()); | |
893 int i = 0; | |
894 while (i < length) { | |
895 uint16_t pid = nack_list[i++]; | |
896 // Bitmask specifies losses in any of the 16 packets following the pid. | |
897 uint16_t bitmask = 0; | |
898 while (i < length) { | |
899 int shift = static_cast<uint16_t>(nack_list[i] - pid) - 1; | |
900 if (shift >= 0 && shift <= 15) { | |
901 bitmask |= (1 << shift); | |
902 ++i; | |
903 } else { | |
904 break; | |
905 } | |
906 } | |
907 RTCPUtility::RTCPPacketRTPFBNACKItem item; | |
908 item.PacketID = pid; | |
909 item.BitMask = bitmask; | |
910 nack_fields_.push_back(item); | |
911 } | |
912 } | |
913 | |
914 bool Rpsi::Create(uint8_t* packet, | 830 bool Rpsi::Create(uint8_t* packet, |
915 size_t* index, | 831 size_t* index, |
916 size_t max_length, | 832 size_t max_length, |
917 RtcpPacket::PacketReadyCallback* callback) const { | 833 RtcpPacket::PacketReadyCallback* callback) const { |
918 assert(rpsi_.NumberOfValidBits > 0); | 834 assert(rpsi_.NumberOfValidBits > 0); |
919 while (*index + BlockLength() > max_length) { | 835 while (*index + BlockLength() > max_length) { |
920 if (!OnBufferFull(packet, index, callback)) | 836 if (!OnBufferFull(packet, index, callback)) |
921 return false; | 837 return false; |
922 } | 838 } |
923 const uint8_t kFmt = 3; | 839 const uint8_t kFmt = 3; |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 return length_; | 1048 return length_; |
1133 } | 1049 } |
1134 | 1050 |
1135 void RawPacket::SetLength(size_t length) { | 1051 void RawPacket::SetLength(size_t length) { |
1136 assert(length <= buffer_length_); | 1052 assert(length <= buffer_length_); |
1137 length_ = length; | 1053 length_ = length; |
1138 } | 1054 } |
1139 | 1055 |
1140 } // namespace rtcp | 1056 } // namespace rtcp |
1141 } // namespace webrtc | 1057 } // namespace webrtc |
OLD | NEW |