PacketBuffer now can save how many times a packet has been nacked.

Also save size/max nack count in the FrameObject/RtpFrameObject.

BUG=webrtc:5514
R=stefan@webrtc.org

Review URL: https://codereview.webrtc.org/1988653002 .

Cr-Commit-Position: refs/heads/master@{#12863}
This commit is contained in:
philipel
2016-05-24 10:20:47 +02:00
parent f1a9a545ff
commit 5ceaaae368
6 changed files with 91 additions and 9 deletions

View File

@ -24,10 +24,14 @@ FrameObject::FrameObject()
RtpFrameObject::RtpFrameObject(PacketBuffer* packet_buffer,
uint16_t first_seq_num,
uint16_t last_seq_num)
uint16_t last_seq_num,
size_t frame_size,
int times_nacked)
: packet_buffer_(packet_buffer),
first_seq_num_(first_seq_num),
last_seq_num_(last_seq_num) {
last_seq_num_(last_seq_num),
times_nacked_(times_nacked) {
size = frame_size;
VCMPacket* packet = packet_buffer_->GetPacket(first_seq_num);
if (packet) {
frame_type_ = packet->frameType;
@ -47,6 +51,10 @@ uint16_t RtpFrameObject::last_seq_num() const {
return last_seq_num_;
}
int RtpFrameObject::times_nacked() const {
return times_nacked_;
}
FrameType RtpFrameObject::frame_type() const {
return frame_type_;
}

View File

@ -36,6 +36,8 @@ class FrameObject {
size_t num_references;
uint16_t references[kMaxFrameReferences];
bool inter_layer_predicted;
size_t size;
};
class PacketBuffer;
@ -44,11 +46,14 @@ class RtpFrameObject : public FrameObject {
public:
RtpFrameObject(PacketBuffer* packet_buffer,
uint16_t first_seq_num,
uint16_t last_seq_num);
uint16_t last_seq_num,
size_t frame_size,
int times_nacked);
~RtpFrameObject();
uint16_t first_seq_num() const;
uint16_t last_seq_num() const;
int times_nacked() const;
FrameType frame_type() const;
VideoCodecType codec_type() const;
bool GetBitstream(uint8_t* destination) const override;
@ -60,6 +65,10 @@ class RtpFrameObject : public FrameObject {
VideoCodecType codec_type_;
uint16_t first_seq_num_;
uint16_t last_seq_num_;
// Equal to times nacked of the packet with the highet times nacked
// belonging to this frame.
int times_nacked_;
};
} // namespace video_coding

View File

@ -24,6 +24,7 @@ VCMPacket::VCMPacket()
dataPtr(NULL),
sizeBytes(0),
markerBit(false),
timesNacked(-1),
frameType(kEmptyFrame),
codec(kVideoCodecUnknown),
isFirstPacket(false),
@ -43,6 +44,7 @@ VCMPacket::VCMPacket(const uint8_t* ptr,
dataPtr(ptr),
sizeBytes(size),
markerBit(rtpHeader.header.markerBit),
timesNacked(-1),
frameType(rtpHeader.frameType),
codec(kVideoCodecUnknown),
@ -67,6 +69,7 @@ VCMPacket::VCMPacket(const uint8_t* ptr,
dataPtr(ptr),
sizeBytes(size),
markerBit(mBit),
timesNacked(-1),
frameType(kVideoFrameDelta),
codec(kVideoCodecUnknown),
@ -85,6 +88,7 @@ void VCMPacket::Reset() {
dataPtr = NULL;
sizeBytes = 0;
markerBit = false;
timesNacked = -1;
frameType = kEmptyFrame;
codec = kVideoCodecUnknown;
isFirstPacket = false;

View File

@ -39,6 +39,7 @@ class VCMPacket {
const uint8_t* dataPtr;
size_t sizeBytes;
bool markerBit;
int timesNacked;
FrameType frameType;
VideoCodecType codec;

View File

@ -137,18 +137,28 @@ void PacketBuffer::FindFrames(uint16_t seq_num) {
// If all packets of the frame is continuous, find the first packet of the
// frame and create an RtpFrameObject.
if (sequence_buffer_[index].frame_end) {
int start_index = index;
size_t frame_size = 0;
int max_nack_count = -1;
uint16_t start_seq_num = seq_num;
while (!sequence_buffer_[start_index].frame_begin) {
// Find the start index by searching backward until the packet with
// the |frame_begin| flag is set.
int start_index = index;
while (true) {
frame_size += data_buffer_[start_index].sizeBytes;
max_nack_count = std::max(
max_nack_count, data_buffer_[start_index].timesNacked);
sequence_buffer_[start_index].frame_created = true;
if (sequence_buffer_[start_index].frame_begin)
break;
start_index = start_index > 0 ? start_index - 1 : size_ - 1;
start_seq_num--;
}
sequence_buffer_[start_index].frame_created = true;
std::unique_ptr<RtpFrameObject> frame(
new RtpFrameObject(this, start_seq_num, seq_num));
std::unique_ptr<RtpFrameObject> frame(new RtpFrameObject(
this, start_seq_num, seq_num, frame_size, max_nack_count));
reference_finder_.ManageFrame(std::move(frame));
}

View File

@ -265,6 +265,56 @@ TEST_F(TestPacketBuffer, InsertDuplicatePacket) {
EXPECT_TRUE(packet_buffer_->InsertPacket(packet));
}
TEST_F(TestPacketBuffer, NackCount) {
uint16_t seq_num = Rand();
VCMPacket packet;
packet.codec = kVideoCodecGeneric;
packet.seqNum = seq_num;
packet.frameType = kVideoFrameKey;
packet.isFirstPacket = true;
packet.markerBit = false;
packet.sizeBytes = 0;
packet.dataPtr = nullptr;
packet.timesNacked = 0;
packet_buffer_->InsertPacket(packet);
packet.seqNum++;
packet.isFirstPacket = false;
packet.timesNacked = 1;
packet_buffer_->InsertPacket(packet);
packet.seqNum++;
packet.timesNacked = 3;
packet_buffer_->InsertPacket(packet);
packet.seqNum++;
packet.markerBit = true;
packet.timesNacked = 1;
packet_buffer_->InsertPacket(packet);
ASSERT_EQ(1UL, frames_from_callback_.size());
FrameObject* frame = frames_from_callback_.begin()->second.get();
RtpFrameObject* rtp_frame = static_cast<RtpFrameObject*>(frame);
EXPECT_EQ(3, rtp_frame->times_nacked());
}
TEST_F(TestPacketBuffer, FrameSize) {
uint16_t seq_num = Rand();
uint8_t data[] = {1, 2, 3, 4, 5};
// seq_num , kf, frst, lst, size, data
InsertGeneric(seq_num , kT, kT , kF , 5 , data);
InsertGeneric(seq_num + 1, kT, kF , kF , 5 , data);
InsertGeneric(seq_num + 2, kT, kF , kF , 5 , data);
InsertGeneric(seq_num + 3, kT, kF , kT , 5 , data);
ASSERT_EQ(1UL, frames_from_callback_.size());
EXPECT_EQ(20UL, frames_from_callback_.begin()->second->size);
}
TEST_F(TestPacketBuffer, ExpandBuffer) {
uint16_t seq_num = Rand();