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_] +
|
payload_bytes_sent_ + part_info_.fragmentationLength[part_ix_] +
|
||||||
FirstHeaderExtraLength(); // Add header extra length to payload length.
|
FirstHeaderExtraLength(); // Add header extra length to payload length.
|
||||||
int rem_payload_len = max_payload_len - vp8_header_bytes_;
|
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,
|
while (int next_size = CalcNextSize(rem_payload_len, remaining_in_partition,
|
||||||
split_payload))
|
split_payload))
|
||||||
@ -153,7 +154,7 @@ int RtpFormatVp8::NextPacket(int max_payload_len, WebRtc_UWord8* buffer,
|
|||||||
|
|
||||||
*last_packet = (payload_bytes_sent_ >= payload_size_);
|
*last_packet = (payload_bytes_sent_ >= payload_size_);
|
||||||
assert(!*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,
|
int RtpFormatVp8::WriteHeaderAndPayload(int payload_bytes,
|
||||||
|
@ -63,7 +63,9 @@ public:
|
|||||||
// bytes_to_send is an output variable that will contain number of bytes
|
// 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
|
// 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
|
// 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 NextPacket(int max_payload_len, WebRtc_UWord8* buffer,
|
||||||
int* bytes_to_send, bool* last_packet);
|
int* bytes_to_send, bool* last_packet);
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ TEST_F(RtpFormatVp8Test, TestStrictMode)
|
|||||||
|
|
||||||
// Second partition
|
// Second partition
|
||||||
// Get first (and only) packet
|
// 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,
|
CheckPacket(send_bytes, 11, last,
|
||||||
first_in_frame,
|
first_in_frame,
|
||||||
/* frag_start */ true,
|
/* frag_start */ true,
|
||||||
@ -168,33 +168,32 @@ TEST_F(RtpFormatVp8Test, TestStrictMode)
|
|||||||
|
|
||||||
// Third partition
|
// Third partition
|
||||||
// Get first packet (of four)
|
// 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,
|
CheckPacket(send_bytes, 4, last,
|
||||||
first_in_frame,
|
first_in_frame,
|
||||||
/* frag_start */ true,
|
/* frag_start */ true,
|
||||||
/* frag_end */ false);
|
/* frag_end */ false);
|
||||||
|
|
||||||
// Get second packet (of four)
|
// 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,
|
CheckPacket(send_bytes, 3, last,
|
||||||
first_in_frame,
|
first_in_frame,
|
||||||
/* frag_start */ false,
|
/* frag_start */ false,
|
||||||
/* frag_end */ false);
|
/* frag_end */ false);
|
||||||
|
|
||||||
// Get third packet (of four)
|
// 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,
|
CheckPacket(send_bytes, 4, last,
|
||||||
first_in_frame,
|
first_in_frame,
|
||||||
/* frag_start */ false,
|
/* frag_start */ false,
|
||||||
/* frag_end */ false);
|
/* frag_end */ false);
|
||||||
|
|
||||||
// Get fourth and last packet
|
// 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,
|
CheckPacket(send_bytes, 3, last,
|
||||||
first_in_frame,
|
first_in_frame,
|
||||||
/* frag_start */ false,
|
/* frag_start */ false,
|
||||||
/* frag_end */ true);
|
/* frag_end */ true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(RtpFormatVp8Test, TestAggregateMode)
|
TEST_F(RtpFormatVp8Test, TestAggregateMode)
|
||||||
@ -226,12 +225,11 @@ TEST_F(RtpFormatVp8Test, TestAggregateMode)
|
|||||||
|
|
||||||
// get third packet
|
// get third packet
|
||||||
// last two partitions aggregated
|
// 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,
|
CheckPacket(send_bytes, 21, last,
|
||||||
first_in_frame,
|
first_in_frame,
|
||||||
/* frag_start */ true,
|
/* frag_start */ true,
|
||||||
/* frag_end */ true);
|
/* frag_end */ true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(RtpFormatVp8Test, TestSloppyMode)
|
TEST_F(RtpFormatVp8Test, TestSloppyMode)
|
||||||
@ -262,7 +260,7 @@ TEST_F(RtpFormatVp8Test, TestSloppyMode)
|
|||||||
|
|
||||||
// get third packet
|
// get third packet
|
||||||
// fragments of second and third partitions
|
// 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,
|
CheckPacket(send_bytes, 9, last,
|
||||||
first_in_frame,
|
first_in_frame,
|
||||||
/* frag_start */ false,
|
/* frag_start */ false,
|
||||||
@ -270,12 +268,11 @@ TEST_F(RtpFormatVp8Test, TestSloppyMode)
|
|||||||
|
|
||||||
// get fourth packet
|
// get fourth packet
|
||||||
// second half of last partition
|
// 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,
|
CheckPacket(send_bytes, 7, last,
|
||||||
first_in_frame,
|
first_in_frame,
|
||||||
/* frag_start */ false,
|
/* frag_start */ false,
|
||||||
/* frag_end */ true);
|
/* frag_end */ true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that sloppy mode is forced if fragmentation info is missing.
|
// Verify that sloppy mode is forced if fragmentation info is missing.
|
||||||
@ -320,7 +317,6 @@ TEST_F(RtpFormatVp8Test, TestSloppyModeFallback)
|
|||||||
first_in_frame,
|
first_in_frame,
|
||||||
/* frag_start */ false,
|
/* frag_start */ false,
|
||||||
/* frag_end */ true);
|
/* frag_end */ true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that non-reference bit is set.
|
// Verify that non-reference bit is set.
|
||||||
|
@ -1226,14 +1226,10 @@ RTPSenderVideo::SendVP8(const FrameType frameType,
|
|||||||
const RTPVideoTypeHeader* rtpTypeHdr)
|
const RTPVideoTypeHeader* rtpTypeHdr)
|
||||||
{
|
{
|
||||||
const WebRtc_UWord16 rtpHeaderLength = _rtpSender.RTPHeaderLength();
|
const WebRtc_UWord16 rtpHeaderLength = _rtpSender.RTPHeaderLength();
|
||||||
WebRtc_UWord16 vp8HeaderLength = 1;
|
|
||||||
int payloadBytesInPacket = 0;
|
|
||||||
WebRtc_Word32 bytesSent = 0;
|
|
||||||
|
|
||||||
WebRtc_Word32 payloadBytesToSend = payloadSize;
|
WebRtc_Word32 payloadBytesToSend = payloadSize;
|
||||||
const WebRtc_UWord8* data = payloadData;
|
const WebRtc_UWord8* data = payloadData;
|
||||||
|
|
||||||
WebRtc_UWord8 dataBuffer[IP_PACKET_SIZE];
|
|
||||||
WebRtc_UWord16 maxPayloadLengthVP8 = _rtpSender.MaxPayloadLength()
|
WebRtc_UWord16 maxPayloadLengthVP8 = _rtpSender.MaxPayloadLength()
|
||||||
- FECPacketOverhead() - rtpHeaderLength;
|
- FECPacketOverhead() - rtpHeaderLength;
|
||||||
|
|
||||||
@ -1242,28 +1238,40 @@ RTPSenderVideo::SendVP8(const FrameType frameType,
|
|||||||
*fragmentation, kStrict);
|
*fragmentation, kStrict);
|
||||||
|
|
||||||
bool last = false;
|
bool last = false;
|
||||||
|
_numberFirstPartition = 0;
|
||||||
|
int numberFirstPartition = 0; // local counter
|
||||||
while (!last)
|
while (!last)
|
||||||
{
|
{
|
||||||
// Write VP8 Payload Descriptor and VP8 payload.
|
// Write VP8 Payload Descriptor and VP8 payload.
|
||||||
if (packetizer.NextPacket(maxPayloadLengthVP8,
|
WebRtc_UWord8 dataBuffer[IP_PACKET_SIZE] = {0};
|
||||||
&dataBuffer[rtpHeaderLength], &payloadBytesInPacket, &last) < 0)
|
int payloadBytesInPacket = 0;
|
||||||
|
int packetStartPartition =
|
||||||
|
packetizer.NextPacket(maxPayloadLengthVP8,
|
||||||
|
&dataBuffer[rtpHeaderLength],
|
||||||
|
&payloadBytesInPacket, &last);
|
||||||
|
if (packetStartPartition == 0)
|
||||||
|
{
|
||||||
|
++numberFirstPartition;
|
||||||
|
}
|
||||||
|
else if (packetStartPartition < 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// numberFirstPartition has reached the final value.
|
||||||
|
_numberFirstPartition = numberFirstPartition;
|
||||||
|
}
|
||||||
|
|
||||||
// Write RTP header.
|
// Write RTP header.
|
||||||
// Set marker bit true if this is the last packet in frame.
|
// Set marker bit true if this is the last packet in frame.
|
||||||
_rtpSender.BuildRTPheader(dataBuffer, payloadType, last,
|
_rtpSender.BuildRTPheader(dataBuffer, payloadType, last,
|
||||||
captureTimeStamp);
|
captureTimeStamp);
|
||||||
|
|
||||||
//TODO (marpan): Set the _numberFirstPartition
|
|
||||||
|
|
||||||
if (-1 == SendVideoPacket(frameType, dataBuffer, payloadBytesInPacket,
|
if (-1 == SendVideoPacket(frameType, dataBuffer, payloadBytesInPacket,
|
||||||
rtpHeaderLength))
|
rtpHeaderLength))
|
||||||
{
|
{
|
||||||
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
|
return -1;
|
||||||
"RTPSenderVideo::SendVP8 failed to send packet number"
|
|
||||||
" %d", _rtpSender.SequenceNumber());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user