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:
parent
dd8076044a
commit
7d3a2a3bca
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user