Set _numberFirstPartition when packetizing VP8 frames

The variable _numberFirstPartition is now set in RTPSenderVideo::SendVP8.
The number of packets that contains data from the first partition
is not known until all packets have been packetized (at least all
first-partition packets). Therefore, the packetization loop in SendVP8
had to be broken up into two loops. The first loop gets all packets from
the VP8 packetizer (RtpFormatVp8) and puts them in a vector. The second
loop sends all packets from the vector to SendVideoPacket.
Review URL: http://webrtc-codereview.appspot.com/56004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@231 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
hlundin@google.com 2011-07-18 22:34:17 +00:00
parent dd8076044a
commit 7d3a2a3bca
4 changed files with 32 additions and 25 deletions

View File

@ -104,6 +104,7 @@ int RtpFormatVp8::NextPacket(int max_payload_len, WebRtc_UWord8* buffer,
payload_bytes_sent_ + part_info_.fragmentationLength[part_ix_] +
FirstHeaderExtraLength(); // Add header extra length to payload length.
int rem_payload_len = max_payload_len - vp8_header_bytes_;
const int first_partition_in_packet = part_ix_;
while (int next_size = CalcNextSize(rem_payload_len, remaining_in_partition,
split_payload))
@ -153,7 +154,7 @@ int RtpFormatVp8::NextPacket(int max_payload_len, WebRtc_UWord8* buffer,
*last_packet = (payload_bytes_sent_ >= payload_size_);
assert(!*last_packet || (payload_bytes_sent_ == payload_size_));
return 0;
return first_partition_in_packet;
}
int RtpFormatVp8::WriteHeaderAndPayload(int payload_bytes,

View File

@ -63,7 +63,9 @@ public:
// bytes_to_send is an output variable that will contain number of bytes
// written to buffer. Parameter last_packet is true for the last packet of
// the frame, false otherwise (i.e., call the function again to get the
// next packet). Returns negative on error, zero otherwise.
// next packet). Returns the partition index from which the first payload
// byte in the packet is taken, with the first partition having index 0;
// returns negative on error.
int NextPacket(int max_payload_len, WebRtc_UWord8* buffer,
int* bytes_to_send, bool* last_packet);

View File

@ -160,7 +160,7 @@ TEST_F(RtpFormatVp8Test, TestStrictMode)
// Second partition
// Get first (and only) packet
EXPECT_EQ(0, packetizer.NextPacket(20, buffer_, &send_bytes, &last));
EXPECT_EQ(1, packetizer.NextPacket(20, buffer_, &send_bytes, &last));
CheckPacket(send_bytes, 11, last,
first_in_frame,
/* frag_start */ true,
@ -168,33 +168,32 @@ TEST_F(RtpFormatVp8Test, TestStrictMode)
// Third partition
// Get first packet (of four)
EXPECT_EQ(0, packetizer.NextPacket(4, buffer_, &send_bytes, &last));
EXPECT_EQ(2, packetizer.NextPacket(4, buffer_, &send_bytes, &last));
CheckPacket(send_bytes, 4, last,
first_in_frame,
/* frag_start */ true,
/* frag_end */ false);
// Get second packet (of four)
EXPECT_EQ(0, packetizer.NextPacket(4, buffer_, &send_bytes, &last));
EXPECT_EQ(2, packetizer.NextPacket(4, buffer_, &send_bytes, &last));
CheckPacket(send_bytes, 3, last,
first_in_frame,
/* frag_start */ false,
/* frag_end */ false);
// Get third packet (of four)
EXPECT_EQ(0, packetizer.NextPacket(4, buffer_, &send_bytes, &last));
EXPECT_EQ(2, packetizer.NextPacket(4, buffer_, &send_bytes, &last));
CheckPacket(send_bytes, 4, last,
first_in_frame,
/* frag_start */ false,
/* frag_end */ false);
// Get fourth and last packet
EXPECT_EQ(0, packetizer.NextPacket(4, buffer_, &send_bytes, &last));
EXPECT_EQ(2, packetizer.NextPacket(4, buffer_, &send_bytes, &last));
CheckPacket(send_bytes, 3, last,
first_in_frame,
/* frag_start */ false,
/* frag_end */ true);
}
TEST_F(RtpFormatVp8Test, TestAggregateMode)
@ -226,12 +225,11 @@ TEST_F(RtpFormatVp8Test, TestAggregateMode)
// get third packet
// last two partitions aggregated
EXPECT_EQ(0, packetizer.NextPacket(25, buffer_, &send_bytes, &last));
EXPECT_EQ(1, packetizer.NextPacket(25, buffer_, &send_bytes, &last));
CheckPacket(send_bytes, 21, last,
first_in_frame,
/* frag_start */ true,
/* frag_end */ true);
}
TEST_F(RtpFormatVp8Test, TestSloppyMode)
@ -262,7 +260,7 @@ TEST_F(RtpFormatVp8Test, TestSloppyMode)
// get third packet
// fragments of second and third partitions
EXPECT_EQ(0, packetizer.NextPacket(9, buffer_, &send_bytes, &last));
EXPECT_EQ(1, packetizer.NextPacket(9, buffer_, &send_bytes, &last));
CheckPacket(send_bytes, 9, last,
first_in_frame,
/* frag_start */ false,
@ -270,12 +268,11 @@ TEST_F(RtpFormatVp8Test, TestSloppyMode)
// get fourth packet
// second half of last partition
EXPECT_EQ(0, packetizer.NextPacket(9, buffer_, &send_bytes, &last));
EXPECT_EQ(2, packetizer.NextPacket(9, buffer_, &send_bytes, &last));
CheckPacket(send_bytes, 7, last,
first_in_frame,
/* frag_start */ false,
/* frag_end */ true);
}
// Verify that sloppy mode is forced if fragmentation info is missing.
@ -320,7 +317,6 @@ TEST_F(RtpFormatVp8Test, TestSloppyModeFallback)
first_in_frame,
/* frag_start */ false,
/* frag_end */ true);
}
// Verify that non-reference bit is set.

View File

@ -1226,14 +1226,10 @@ RTPSenderVideo::SendVP8(const FrameType frameType,
const RTPVideoTypeHeader* rtpTypeHdr)
{
const WebRtc_UWord16 rtpHeaderLength = _rtpSender.RTPHeaderLength();
WebRtc_UWord16 vp8HeaderLength = 1;
int payloadBytesInPacket = 0;
WebRtc_Word32 bytesSent = 0;
WebRtc_Word32 payloadBytesToSend = payloadSize;
const WebRtc_UWord8* data = payloadData;
WebRtc_UWord8 dataBuffer[IP_PACKET_SIZE];
WebRtc_UWord16 maxPayloadLengthVP8 = _rtpSender.MaxPayloadLength()
- FECPacketOverhead() - rtpHeaderLength;
@ -1242,28 +1238,40 @@ RTPSenderVideo::SendVP8(const FrameType frameType,
*fragmentation, kStrict);
bool last = false;
_numberFirstPartition = 0;
int numberFirstPartition = 0; // local counter
while (!last)
{
// Write VP8 Payload Descriptor and VP8 payload.
if (packetizer.NextPacket(maxPayloadLengthVP8,
&dataBuffer[rtpHeaderLength], &payloadBytesInPacket, &last) < 0)
WebRtc_UWord8 dataBuffer[IP_PACKET_SIZE] = {0};
int payloadBytesInPacket = 0;
int packetStartPartition =
packetizer.NextPacket(maxPayloadLengthVP8,
&dataBuffer[rtpHeaderLength],
&payloadBytesInPacket, &last);
if (packetStartPartition == 0)
{
++numberFirstPartition;
}
else if (packetStartPartition < 0)
{
return -1;
}
else
{
// numberFirstPartition has reached the final value.
_numberFirstPartition = numberFirstPartition;
}
// Write RTP header.
// Set marker bit true if this is the last packet in frame.
_rtpSender.BuildRTPheader(dataBuffer, payloadType, last,
captureTimeStamp);
//TODO (marpan): Set the _numberFirstPartition
if (-1 == SendVideoPacket(frameType, dataBuffer, payloadBytesInPacket,
rtpHeaderLength))
{
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
"RTPSenderVideo::SendVP8 failed to send packet number"
" %d", _rtpSender.SequenceNumber());
return -1;
}
}
return 0;