| Index: webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc
|
| diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc b/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc
|
| index 2d847c17a608ba5f64dae5f938b3ca4b7689693f..b5e8d518114a699098fa05f4f7d118013fcb0578 100644
|
| --- a/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc
|
| +++ b/webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.cc
|
| @@ -20,12 +20,14 @@ namespace webrtc {
|
| static const size_t kGenericHeaderLength = 1;
|
|
|
| RtpPacketizerGeneric::RtpPacketizerGeneric(FrameType frame_type,
|
| - size_t max_payload_len)
|
| + size_t max_payload_len,
|
| + size_t last_packet_extension_len)
|
| : payload_data_(NULL),
|
| payload_size_(0),
|
| max_payload_len_(max_payload_len - kGenericHeaderLength),
|
| - frame_type_(frame_type) {
|
| -}
|
| + last_packet_extension_len_(last_packet_extension_len),
|
| + frame_type_(frame_type),
|
| + num_packets_(0) {}
|
|
|
| RtpPacketizerGeneric::~RtpPacketizerGeneric() {
|
| }
|
| @@ -37,42 +39,59 @@ void RtpPacketizerGeneric::SetPayloadData(
|
| payload_data_ = payload_data;
|
| payload_size_ = payload_size;
|
|
|
| + size_t total_data = payload_size_ + last_packet_extension_len_;
|
| +
|
| // Fragment packets more evenly by splitting the payload up evenly.
|
| - size_t num_packets =
|
| - (payload_size_ + max_payload_len_ - 1) / max_payload_len_;
|
| - payload_length_ = (payload_size_ + num_packets - 1) / num_packets;
|
| - assert(payload_length_ <= max_payload_len_);
|
| + num_packets_ = (total_data + max_payload_len_ - 1) / max_payload_len_;
|
| + payload_per_packet_ = (total_data + num_packets_ - 1) / num_packets_;
|
| + smaller_packets_ = num_packets_ - total_data % num_packets_;
|
| + if (smaller_packets_ == num_packets_)
|
| + smaller_packets_ = 0;
|
| + assert(payload_per_packet_ <= max_payload_len_);
|
|
|
| generic_header_ = RtpFormatVideoGeneric::kFirstPacketBit;
|
| + if (frame_type_ == kVideoFrameKey) {
|
| + generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit;
|
| + }
|
| }
|
|
|
| -bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet,
|
| - bool* last_packet) {
|
| +size_t RtpPacketizerGeneric::TotalPackets() {
|
| + return num_packets_;
|
| +}
|
| +
|
| +bool RtpPacketizerGeneric::NextPacket(RtpPacketToSend* packet) {
|
| RTC_DCHECK(packet);
|
| - RTC_DCHECK(last_packet);
|
| - if (payload_size_ < payload_length_) {
|
| - payload_length_ = payload_size_;
|
| + // last smaller_packets_ packets are 1 byte smaller than previous packets.
|
| + if (num_packets_ == smaller_packets_)
|
| + payload_per_packet_--;
|
| + // whole payload fit into this packet
|
| + size_t current_payload = payload_per_packet_;
|
| + if (payload_size_ <= current_payload) {
|
| + current_payload = payload_size_;
|
| + // But this is the pre-last packet. Leave at least 1 payload byte for the
|
| + // last packet. Should happen only if extensions take at least half of
|
| + // available capacity.
|
| + if (num_packets_ == 2) {
|
| + RTC_DCHECK(last_packet_extension_len_ >= max_payload_len_ / 2);
|
| + current_payload -= 1;
|
| + }
|
| }
|
| -
|
| - payload_size_ -= payload_length_;
|
| - RTC_DCHECK_LE(payload_length_, max_payload_len_);
|
| + RTC_DCHECK_LE(current_payload, max_payload_len_);
|
|
|
| uint8_t* out_ptr =
|
| - packet->AllocatePayload(kGenericHeaderLength + payload_length_);
|
| + packet->AllocatePayload(kGenericHeaderLength + current_payload);
|
| // Put generic header in packet
|
| - if (frame_type_ == kVideoFrameKey) {
|
| - generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit;
|
| - }
|
| out_ptr[0] = generic_header_;
|
| // Remove first-packet bit, following packets are intermediate
|
| generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit;
|
|
|
| // Put payload in packet
|
| - memcpy(out_ptr + kGenericHeaderLength, payload_data_, payload_length_);
|
| - payload_data_ += payload_length_;
|
| + memcpy(out_ptr + kGenericHeaderLength, payload_data_, current_payload);
|
| + payload_data_ += current_payload;
|
| + payload_size_ -= current_payload;
|
| + num_packets_--;
|
|
|
| - *last_packet = payload_size_ <= 0;
|
| - packet->SetMarker(*last_packet);
|
| + packet->SetMarker(payload_size_ == 0);
|
| return true;
|
| }
|
|
|
|
|