| 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_(0) {} |
| 29 | 31 |
| 30 RtpPacketizerGeneric::~RtpPacketizerGeneric() { | 32 RtpPacketizerGeneric::~RtpPacketizerGeneric() { |
| 31 } | 33 } |
| 32 | 34 |
| 33 void RtpPacketizerGeneric::SetPayloadData( | 35 void 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 |
| 42 size_t total_data = payload_size_ + last_packet_extension_len_; |
| 43 |
| 40 // Fragment packets more evenly by splitting the payload up evenly. | 44 // Fragment packets more evenly by splitting the payload up evenly. |
| 41 size_t num_packets = | 45 num_packets_ = (total_data + max_payload_len_ - 1) / max_payload_len_; |
| 42 (payload_size_ + max_payload_len_ - 1) / max_payload_len_; | 46 payload_per_packet_ = (total_data + num_packets_ - 1) / num_packets_; |
| 43 payload_length_ = (payload_size_ + num_packets - 1) / num_packets; | 47 smaller_packets_ = num_packets_ - total_data % num_packets_; |
| 44 assert(payload_length_ <= max_payload_len_); | 48 if (smaller_packets_ == num_packets_) |
| 49 smaller_packets_ = 0; |
| 50 assert(payload_per_packet_ <= max_payload_len_); |
| 45 | 51 |
| 46 generic_header_ = RtpFormatVideoGeneric::kFirstPacketBit; | 52 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) { | 53 if (frame_type_ == kVideoFrameKey) { |
| 64 generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit; | 54 generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit; |
| 65 } | 55 } |
| 56 } |
| 57 |
| 58 size_t RtpPacketizerGeneric::TotalPackets() { |
| 59 return num_packets_; |
| 60 } |
| 61 |
| 62 bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet) { |
| 63 RTC_DCHECK(packet); |
| 64 // last smaller_packets_ packets are 1 byte smaller than previous packets. |
| 65 if (num_packets_ == smaller_packets_) |
| 66 payload_per_packet_--; |
| 67 // whole payload fit into this packet |
| 68 size_t current_payload = payload_per_packet_; |
| 69 if (payload_size_ <= current_payload) { |
| 70 current_payload = payload_size_; |
| 71 // But this is the pre-last packet. Leave at least 1 payload byte for the |
| 72 // last packet. Should happen only if extensions take at least half of |
| 73 // available capacity. |
| 74 if (num_packets_ == 2) { |
| 75 RTC_DCHECK(last_packet_extension_len_ >= max_payload_len_ / 2); |
| 76 current_payload -= 1; |
| 77 } |
| 78 } |
| 79 RTC_DCHECK_LE(current_payload, max_payload_len_); |
| 80 |
| 81 uint8_t* out_ptr = |
| 82 packet->AllocatePayload(kGenericHeaderLength + current_payload); |
| 83 // Put generic header in packet |
| 66 out_ptr[0] = generic_header_; | 84 out_ptr[0] = generic_header_; |
| 67 // Remove first-packet bit, following packets are intermediate | 85 // Remove first-packet bit, following packets are intermediate |
| 68 generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit; | 86 generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit; |
| 69 | 87 |
| 70 // Put payload in packet | 88 // Put payload in packet |
| 71 memcpy(out_ptr + kGenericHeaderLength, payload_data_, payload_length_); | 89 memcpy(out_ptr + kGenericHeaderLength, payload_data_, current_payload); |
| 72 payload_data_ += payload_length_; | 90 payload_data_ += current_payload; |
| 91 payload_size_ -= current_payload; |
| 92 num_packets_--; |
| 73 | 93 |
| 74 *last_packet = payload_size_ <= 0; | 94 packet->SetMarker(payload_size_ == 0); |
| 75 packet->SetMarker(*last_packet); | |
| 76 return true; | 95 return true; |
| 77 } | 96 } |
| 78 | 97 |
| 79 ProtectionType RtpPacketizerGeneric::GetProtectionType() { | 98 ProtectionType RtpPacketizerGeneric::GetProtectionType() { |
| 80 return kProtectedPacket; | 99 return kProtectedPacket; |
| 81 } | 100 } |
| 82 | 101 |
| 83 StorageType RtpPacketizerGeneric::GetStorageType( | 102 StorageType RtpPacketizerGeneric::GetStorageType( |
| 84 uint32_t retransmission_settings) { | 103 uint32_t retransmission_settings) { |
| 85 return kAllowRetransmission; | 104 return kAllowRetransmission; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 109 (generic_header & RtpFormatVideoGeneric::kFirstPacketBit) != 0; | 128 (generic_header & RtpFormatVideoGeneric::kFirstPacketBit) != 0; |
| 110 parsed_payload->type.Video.codec = kRtpVideoGeneric; | 129 parsed_payload->type.Video.codec = kRtpVideoGeneric; |
| 111 parsed_payload->type.Video.width = 0; | 130 parsed_payload->type.Video.width = 0; |
| 112 parsed_payload->type.Video.height = 0; | 131 parsed_payload->type.Video.height = 0; |
| 113 | 132 |
| 114 parsed_payload->payload = payload_data; | 133 parsed_payload->payload = payload_data; |
| 115 parsed_payload->payload_length = payload_data_length; | 134 parsed_payload->payload_length = payload_data_length; |
| 116 return true; | 135 return true; |
| 117 } | 136 } |
| 118 } // namespace webrtc | 137 } // namespace webrtc |
| OLD | NEW |