From f561f488fc444abc96f2ad05cdf035b1c3b14f53 Mon Sep 17 00:00:00 2001 From: "henrika@google.com" Date: Wed, 15 Jun 2011 08:37:18 +0000 Subject: [PATCH] Temporary rollback to be able to build on Windows. Will be fixed soon. git-svn-id: http://webrtc.googlecode.com/svn/trunk@82 4adac7df-926f-26a2-2b94-8c16560cd09d --- modules/rtp_rtcp/source/rtp_format_vp8.cc | 184 +++++++++++--------- modules/rtp_rtcp/source/rtp_format_vp8.h | 32 +--- modules/rtp_rtcp/source/rtp_sender_video.cc | 2 +- 3 files changed, 108 insertions(+), 110 deletions(-) diff --git a/modules/rtp_rtcp/source/rtp_format_vp8.cc b/modules/rtp_rtcp/source/rtp_format_vp8.cc index c7cb0bf29c..06b6dfb851 100644 --- a/modules/rtp_rtcp/source/rtp_format_vp8.cc +++ b/modules/rtp_rtcp/source/rtp_format_vp8.cc @@ -11,133 +11,147 @@ #include "rtp_format_vp8.h" #include // assert -#include // ceil, round #include // memcpy namespace webrtc { -// Define how the VP8PacketizerModes are implemented. -// Modes are: kStrict, kAggregate, kSloppy. -const RtpFormatVp8::AggregationMode RtpFormatVp8::aggr_modes_[kNumModes] = - { kAggrNone, kAggrPartitions, kAggrFragments }; -const bool RtpFormatVp8::bal_modes_[kNumModes] = - { true, false, false }; -const bool RtpFormatVp8::sep_first_modes_[kNumModes] = - { true, false, false }; - RtpFormatVp8::RtpFormatVp8(const WebRtc_UWord8* payload_data, WebRtc_UWord32 payload_size, - const RTPFragmentationHeader& fragmentation, + const RTPFragmentationHeader* fragmentation, VP8PacketizerMode mode) : payload_data_(payload_data), payload_size_(payload_size), payload_bytes_sent_(0), - part_ix_(0), + mode_(mode), beginning_(true), first_fragment_(true), - vp8_header_bytes_(1), - aggr_mode_(aggr_modes_[mode]), - balance_(bal_modes_[mode]), - separate_first_(sep_first_modes_[mode]) + vp8_header_bytes_(1) { - part_info_ = fragmentation; + if (fragmentation == NULL) + { + // Cannot do kStrict or kAggregate without fragmentation info. + // Change to kSloppy. + mode_ = kSloppy; + } + else + { + frag_info_ = *fragmentation; + } } RtpFormatVp8::RtpFormatVp8(const WebRtc_UWord8* payload_data, WebRtc_UWord32 payload_size) : payload_data_(payload_data), payload_size_(payload_size), - part_info_(), + frag_info_(), payload_bytes_sent_(0), - part_ix_(0), + mode_(kSloppy), beginning_(true), first_fragment_(true), - vp8_header_bytes_(1), - aggr_mode_(aggr_modes_[kSloppy]), - balance_(bal_modes_[kSloppy]), - separate_first_(sep_first_modes_[kSloppy]) -{ - part_info_.VerifyAndAllocateFragmentationHeader(1); - part_info_.fragmentationLength[0] = payload_size_; - part_info_.fragmentationOffset[0] = 0; -} + vp8_header_bytes_(1) +{} -int RtpFormatVp8::CalcNextSize(int max_payload_len, int remaining_bytes, - bool split_payload) const +int RtpFormatVp8::GetFragIdx() { - if (max_payload_len == 0 || remaining_bytes == 0) + // Which fragment are we in? + int frag_ix = 0; + while ((frag_ix + 1 < frag_info_.fragmentationVectorSize) && + (payload_bytes_sent_ >= frag_info_.fragmentationOffset[frag_ix + 1])) { - return 0; - } - if (!split_payload) - { - return max_payload_len >= remaining_bytes ? remaining_bytes : 0; - } - - if (balance_) - { - // Balance payload sizes to produce (almost) equal size - // fragments. - // Number of fragments for remaining_bytes: - int num_frags = ceil( - static_cast(remaining_bytes) / max_payload_len); - // Number of bytes in this fragment: - return static_cast(round( - static_cast(remaining_bytes) / num_frags)); - } - else - { - return max_payload_len >= remaining_bytes ? remaining_bytes - : max_payload_len; + ++frag_ix; } + return frag_ix; } int RtpFormatVp8::NextPacket(int max_payload_len, WebRtc_UWord8* buffer, int* bytes_to_send, bool* last_packet) { - const int num_partitions = part_info_.fragmentationVectorSize; + // Convenience variables + const int num_fragments = frag_info_.fragmentationVectorSize; + int frag_ix = GetFragIdx(); //TODO (hlundin): Store frag_ix as a member? int send_bytes = 0; // How much data to send in this packet. - bool split_payload = true; // Splitting of partitions is initially allowed. - int remaining_in_partition = part_info_.fragmentationOffset[part_ix_] - - payload_bytes_sent_ + part_info_.fragmentationLength[part_ix_]; - int rem_payload_len = max_payload_len - vp8_header_bytes_; + bool end_of_fragment = false; - while (int next_size = CalcNextSize(rem_payload_len, remaining_in_partition, - split_payload)) + switch (mode_) { - send_bytes += next_size; - rem_payload_len -= next_size; - remaining_in_partition -= next_size; - - if (remaining_in_partition == 0 && !(beginning_ && separate_first_)) + case kAggregate: { - // Advance to next partition? - // Check that there are more partitions; verify that we are either - // allowed to aggregate fragments, or that we are allowed to - // aggregate intact partitions and that we started this packet - // with an intact partition (indicated by first_fragment_ == true). - if (part_ix_ + 1 < num_partitions && - ((aggr_mode_ == kAggrFragments) || - (aggr_mode_ == kAggrPartitions && first_fragment_))) + // Check if we are at the beginning of a new partition. + if (first_fragment_) { - remaining_in_partition - = part_info_.fragmentationLength[++part_ix_]; - // Disallow splitting unless kAggrFragments. In kAggrPartitions, - // we can only aggregate intact partitions. - split_payload = (aggr_mode_ == kAggrFragments); + // Check if this fragment fits in one packet. + if (frag_info_.fragmentationLength[frag_ix] + vp8_header_bytes_ + <= max_payload_len) + { + // Pack as many whole partitions we can into this packet; + // don't fragment. + while ((frag_ix < num_fragments) && + (send_bytes + vp8_header_bytes_ + + frag_info_.fragmentationLength[frag_ix] + <= max_payload_len)) + { + send_bytes += frag_info_.fragmentationLength[frag_ix]; + ++frag_ix; + } + + // This packet ends on a complete fragment. + end_of_fragment = true; + break; // Jump out of case statement. + } } + + // Either we are not starting this packet with a new partition, + // or the partition is too large for a packet. + // Move on to "case kStrict". + // NOTE: break intentionally omitted! } - else if (balance_ && remaining_in_partition > 0) + + case kStrict: // Can also continue to here from kAggregate. { + // Find out how much is left to send in the current partition. + const int remaining_bytes = frag_info_.fragmentationOffset[frag_ix] + - payload_bytes_sent_ + frag_info_.fragmentationLength[frag_ix]; + assert(remaining_bytes > 0); + assert(remaining_bytes <= frag_info_.fragmentationLength[frag_ix]); + + if (remaining_bytes + vp8_header_bytes_ > max_payload_len) + { + // send one full packet + send_bytes = max_payload_len - vp8_header_bytes_; + } + else + { + // last packet from this partition + send_bytes = remaining_bytes; + end_of_fragment = true; + } break; } - } - if (remaining_in_partition == 0) - { - ++part_ix_; // Advance to next partition. + + case kSloppy: + { + // Send a full packet, or what is left of the payload. + const int remaining_bytes = payload_size_ - payload_bytes_sent_; + + if (remaining_bytes + vp8_header_bytes_ > max_payload_len) + { + send_bytes = max_payload_len - vp8_header_bytes_; + end_of_fragment = false; + } + else + { + send_bytes = remaining_bytes; + end_of_fragment = true; + } + break; + } + + default: + // Should not end up here + assert(false); + return -1; } - const bool end_of_fragment = (remaining_in_partition == 0); // Write the payload header and the payload to buffer. *bytes_to_send = WriteHeaderAndPayload(send_bytes, end_of_fragment, buffer); if (*bytes_to_send < 0) @@ -145,7 +159,7 @@ int RtpFormatVp8::NextPacket(int max_payload_len, WebRtc_UWord8* buffer, return -1; } - *last_packet = (payload_bytes_sent_ >= payload_size_); + *last_packet = payload_bytes_sent_ >= payload_size_; assert(!*last_packet || (payload_bytes_sent_ == payload_size_)); return 0; } diff --git a/modules/rtp_rtcp/source/rtp_format_vp8.h b/modules/rtp_rtcp/source/rtp_format_vp8.h index 4f2e193c06..c8464a5d93 100644 --- a/modules/rtp_rtcp/source/rtp_format_vp8.h +++ b/modules/rtp_rtcp/source/rtp_format_vp8.h @@ -33,10 +33,9 @@ namespace webrtc enum VP8PacketizerMode { - kStrict = 0, // split partitions if too large; never aggregate, balance size - kAggregate, // split partitions if too large; aggregate whole partitions - kSloppy, // split entire payload without considering partition limits - kNumModes, + kStrict = 0, // split partitions if too large; never aggregate partitions + kAggregate, // split partitions if too large; aggregate whole partitions + kSloppy, // split entire payload without considering partition boundaries }; // Packetizer for VP8. @@ -47,7 +46,7 @@ public: // The payload_data must be exactly one encoded VP8 frame. RtpFormatVp8(const WebRtc_UWord8* payload_data, WebRtc_UWord32 payload_size, - const RTPFragmentationHeader& fragmentation, + const RTPFragmentationHeader* fragmentation, VP8PacketizerMode mode); // Initialize without fragmentation info. Mode kSloppy will be used. @@ -66,20 +65,8 @@ public: int* bytes_to_send, bool* last_packet); private: - enum AggregationMode - { - kAggrNone = 0, // no aggregation - kAggrPartitions, // aggregate intact partitions - kAggrFragments // aggregate intact and fragmented partitions - }; - - static const AggregationMode aggr_modes_[kNumModes]; - static const bool bal_modes_[kNumModes]; - static const bool sep_first_modes_[kNumModes]; - - // Calculate size of next chunk to send. Returns 0 if none can be sent. - int CalcNextSize(int max_payload_len, int remaining_bytes, - bool split_payload) const; + // Determine from which fragment the next byte to send will be taken. + int GetFragIdx(); // Write the payload header and copy the payload to the buffer. // Will copy send_bytes bytes from the current position on the payload data. @@ -90,15 +77,12 @@ private: const WebRtc_UWord8* payload_data_; const WebRtc_UWord32 payload_size_; - RTPFragmentationHeader part_info_; + RTPFragmentationHeader frag_info_; int payload_bytes_sent_; - int part_ix_; + VP8PacketizerMode mode_; bool beginning_; // first partition in this frame bool first_fragment_; // first fragment of a partition const int vp8_header_bytes_; // length of VP8 payload header - AggregationMode aggr_mode_; - bool balance_; - bool separate_first_; }; } diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc index 4f03f85c26..5de67cdafa 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video.cc @@ -1106,7 +1106,7 @@ RTPSenderVideo::SendVP8(const FrameType frameType, WebRtc_UWord16 maxPayloadLengthVP8 = _rtpSender.MaxPayloadLength() - FECPacketOverhead() - rtpHeaderLength; - RtpFormatVp8 packetizer(data, payloadBytesToSend, *fragmentation, kStrict); + RtpFormatVp8 packetizer(data, payloadBytesToSend, fragmentation, kStrict); bool last = false; while (!last)