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 |
11 #include <string> | 11 #include <string> |
12 | 12 |
13 #include "webrtc/base/logging.h" | 13 #include "webrtc/base/logging.h" |
14 #include "webrtc/modules/include/module_common_types.h" | 14 #include "webrtc/modules/include/module_common_types.h" |
15 #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h" | 15 #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h" |
16 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h" | 16 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h" |
17 | 17 |
18 namespace webrtc { | 18 namespace webrtc { |
19 | 19 |
20 static const size_t kGenericHeaderLength = 1; | 20 static const size_t kGenericHeaderLength = 1; |
21 | 21 |
22 RtpPacketizerGeneric::RtpPacketizerGeneric(FrameType frame_type, | 22 RtpPacketizerGeneric::RtpPacketizerGeneric(FrameType frame_type, |
23 size_t max_payload_len) | 23 size_t max_payload_len, |
24 size_t last_packet_extension_len) | |
24 : payload_data_(NULL), | 25 : payload_data_(NULL), |
25 payload_size_(0), | 26 payload_size_(0), |
26 max_payload_len_(max_payload_len - kGenericHeaderLength), | 27 max_payload_len_(max_payload_len - kGenericHeaderLength), |
27 frame_type_(frame_type) { | 28 last_packet_extension_len_(last_packet_extension_len), |
28 } | 29 frame_type_(frame_type), |
30 num_packets_left_(0) {} | |
29 | 31 |
danilchap
2017/05/12 18:56:15
initialize num_smaller_packets_ member too
ilnik
2017/05/15 09:38:33
Done.
| |
30 RtpPacketizerGeneric::~RtpPacketizerGeneric() { | 32 RtpPacketizerGeneric::~RtpPacketizerGeneric() { |
31 } | 33 } |
32 | 34 |
33 void RtpPacketizerGeneric::SetPayloadData( | 35 size_t RtpPacketizerGeneric::SetPayloadData( |
34 const uint8_t* payload_data, | 36 const uint8_t* payload_data, |
35 size_t payload_size, | 37 size_t payload_size, |
36 const RTPFragmentationHeader* fragmentation) { | 38 const RTPFragmentationHeader* fragmentation) { |
37 payload_data_ = payload_data; | 39 payload_data_ = payload_data; |
38 payload_size_ = payload_size; | 40 payload_size_ = payload_size; |
39 | 41 |
40 // Fragment packets more evenly by splitting the payload up evenly. | 42 /* Fragment packets such that they are almost the same size, even accounting |
41 size_t num_packets = | 43 * for larger header in the last packet due to extensions. |
42 (payload_size_ + max_payload_len_ - 1) / max_payload_len_; | 44 * Since we are given how much extra space is occupied by the longer header |
43 payload_length_ = (payload_size_ + num_packets - 1) / num_packets; | 45 * in the last packet, we can pretend that RTP headers are the same, but |
44 assert(payload_length_ <= max_payload_len_); | 46 * there's last_packet_extension_len_ extra payload, to be put at the end of |
47 * the last packet. | |
48 */ | |
49 size_t total_data = payload_size_ + last_packet_extension_len_; | |
danilchap
2017/05/12 18:56:15
may be do not name variable 'data' when it represe
ilnik
2017/05/15 09:38:33
I can't think of any better name.
danilchap
2017/05/15 11:03:17
I think total_size/total_length/total_len/total_b
ilnik
2017/05/15 12:11:38
Done.
| |
50 | |
51 // Minimum needed number of packets to fit payload and extensions. | |
52 num_packets_left_ = (total_data + max_payload_len_ - 1) / max_payload_len_; | |
53 // Given number of packets we will use, calculate average size rounded up. | |
54 payload_len_per_packet_ = | |
55 (total_data + num_packets_left_ - 1) / num_packets_left_; | |
56 // If we can't divide everything perfectly evenly, we put 1 extra byte in some | |
57 // first packets: 14 bytes in 4 packets would be splitted as 4+4+3+3. | |
danilchap
2017/05/12 18:56:15
did you consider 'small packets first, then larger
ilnik
2017/05/15 09:38:33
It's just one byte of difference. Doesn't make muc
danilchap
2017/05/15 11:03:17
function-wise it is sure the same.
It just looked
ilnik
2017/05/15 12:11:38
Acknowledged.
| |
58 // There are exactly total_data % num_packets larger packets. | |
59 num_smaller_packets_ = num_packets_left_ - total_data % num_packets_left_; | |
60 // If all packets are the same size, we already have correct per packet | |
61 // length. | |
62 if (num_smaller_packets_ == num_packets_left_) | |
63 num_smaller_packets_ = 0; | |
64 RTC_DCHECK_LE(payload_len_per_packet_, max_payload_len_); | |
45 | 65 |
46 generic_header_ = RtpFormatVideoGeneric::kFirstPacketBit; | 66 generic_header_ = RtpFormatVideoGeneric::kFirstPacketBit; |
47 } | |
48 | |
49 bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet, | |
50 bool* last_packet) { | |
51 RTC_DCHECK(packet); | |
52 RTC_DCHECK(last_packet); | |
53 if (payload_size_ < payload_length_) { | |
54 payload_length_ = payload_size_; | |
55 } | |
56 | |
57 payload_size_ -= payload_length_; | |
58 RTC_DCHECK_LE(payload_length_, max_payload_len_); | |
59 | |
60 uint8_t* out_ptr = | |
61 packet->AllocatePayload(kGenericHeaderLength + payload_length_); | |
62 // Put generic header in packet | |
63 if (frame_type_ == kVideoFrameKey) { | 67 if (frame_type_ == kVideoFrameKey) { |
64 generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit; | 68 generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit; |
65 } | 69 } |
70 return num_packets_left_; | |
71 } | |
72 | |
73 bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet) { | |
74 RTC_DCHECK(packet); | |
75 if (num_packets_left_ == 0) | |
76 return false; | |
77 // Last smaller_packets_ packets are 1 byte smaller than previous packets. | |
78 // Reduce per packet payload once needed. | |
79 if (num_packets_left_ == num_smaller_packets_) | |
80 payload_len_per_packet_--; | |
81 size_t next_packet_payload_len = payload_len_per_packet_; | |
82 if (payload_size_ <= next_packet_payload_len) { | |
83 // Whole payload fits into this packet | |
84 next_packet_payload_len = payload_size_; | |
85 if (num_packets_left_ == 2) { | |
86 // This is the pre-last packet. Leave at least 1 payload byte for the | |
87 // last packet. | |
88 next_packet_payload_len--; | |
89 RTC_DCHECK_GT(next_packet_payload_len, 0); | |
90 } | |
91 } | |
92 RTC_DCHECK_LE(next_packet_payload_len, max_payload_len_); | |
93 | |
94 uint8_t* out_ptr = | |
95 packet->AllocatePayload(kGenericHeaderLength + next_packet_payload_len); | |
96 // Put generic header in packet. | |
66 out_ptr[0] = generic_header_; | 97 out_ptr[0] = generic_header_; |
67 // Remove first-packet bit, following packets are intermediate | 98 // Remove first-packet bit, following packets are intermediate. |
68 generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit; | 99 generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit; |
69 | 100 |
70 // Put payload in packet | 101 // Put payload in packet. |
71 memcpy(out_ptr + kGenericHeaderLength, payload_data_, payload_length_); | 102 memcpy(out_ptr + kGenericHeaderLength, payload_data_, |
72 payload_data_ += payload_length_; | 103 next_packet_payload_len); |
104 payload_data_ += next_packet_payload_len; | |
105 payload_size_ -= next_packet_payload_len; | |
106 num_packets_left_--; | |
107 // Packets left to produce and data left to split should end at the same time. | |
108 RTC_DCHECK_EQ(num_packets_left_ == 0, payload_size_ == 0); | |
73 | 109 |
74 *last_packet = payload_size_ <= 0; | 110 packet->SetMarker(payload_size_ == 0); |
75 packet->SetMarker(*last_packet); | 111 |
76 return true; | 112 return true; |
77 } | 113 } |
78 | 114 |
79 ProtectionType RtpPacketizerGeneric::GetProtectionType() { | 115 ProtectionType RtpPacketizerGeneric::GetProtectionType() { |
80 return kProtectedPacket; | 116 return kProtectedPacket; |
81 } | 117 } |
82 | 118 |
83 StorageType RtpPacketizerGeneric::GetStorageType( | 119 StorageType RtpPacketizerGeneric::GetStorageType( |
84 uint32_t retransmission_settings) { | 120 uint32_t retransmission_settings) { |
85 return kAllowRetransmission; | 121 return kAllowRetransmission; |
(...skipping 23 matching lines...) Expand all Loading... | |
109 (generic_header & RtpFormatVideoGeneric::kFirstPacketBit) != 0; | 145 (generic_header & RtpFormatVideoGeneric::kFirstPacketBit) != 0; |
110 parsed_payload->type.Video.codec = kRtpVideoGeneric; | 146 parsed_payload->type.Video.codec = kRtpVideoGeneric; |
111 parsed_payload->type.Video.width = 0; | 147 parsed_payload->type.Video.width = 0; |
112 parsed_payload->type.Video.height = 0; | 148 parsed_payload->type.Video.height = 0; |
113 | 149 |
114 parsed_payload->payload = payload_data; | 150 parsed_payload->payload = payload_data; |
115 parsed_payload->payload_length = payload_data_length; | 151 parsed_payload->payload_length = payload_data_length; |
116 return true; | 152 return true; |
117 } | 153 } |
118 } // namespace webrtc | 154 } // namespace webrtc |
OLD | NEW |