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, RtpFrameObject::RtpFrameObject(PacketBuffer* packet_buffer,
uint16_t first_seq_num, 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), : packet_buffer_(packet_buffer),
first_seq_num_(first_seq_num), 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); VCMPacket* packet = packet_buffer_->GetPacket(first_seq_num);
if (packet) { if (packet) {
frame_type_ = packet->frameType; frame_type_ = packet->frameType;
@ -47,6 +51,10 @@ uint16_t RtpFrameObject::last_seq_num() const {
return last_seq_num_; return last_seq_num_;
} }
int RtpFrameObject::times_nacked() const {
return times_nacked_;
}
FrameType RtpFrameObject::frame_type() const { FrameType RtpFrameObject::frame_type() const {
return frame_type_; return frame_type_;
} }

View File

@ -36,6 +36,8 @@ class FrameObject {
size_t num_references; size_t num_references;
uint16_t references[kMaxFrameReferences]; uint16_t references[kMaxFrameReferences];
bool inter_layer_predicted; bool inter_layer_predicted;
size_t size;
}; };
class PacketBuffer; class PacketBuffer;
@ -44,11 +46,14 @@ class RtpFrameObject : public FrameObject {
public: public:
RtpFrameObject(PacketBuffer* packet_buffer, RtpFrameObject(PacketBuffer* packet_buffer,
uint16_t first_seq_num, uint16_t first_seq_num,
uint16_t last_seq_num); uint16_t last_seq_num,
size_t frame_size,
int times_nacked);
~RtpFrameObject(); ~RtpFrameObject();
uint16_t first_seq_num() const; uint16_t first_seq_num() const;
uint16_t last_seq_num() const; uint16_t last_seq_num() const;
int times_nacked() const;
FrameType frame_type() const; FrameType frame_type() const;
VideoCodecType codec_type() const; VideoCodecType codec_type() const;
bool GetBitstream(uint8_t* destination) const override; bool GetBitstream(uint8_t* destination) const override;
@ -60,6 +65,10 @@ class RtpFrameObject : public FrameObject {
VideoCodecType codec_type_; VideoCodecType codec_type_;
uint16_t first_seq_num_; uint16_t first_seq_num_;
uint16_t last_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 } // namespace video_coding

View File

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

View File

@ -39,6 +39,7 @@ class VCMPacket {
const uint8_t* dataPtr; const uint8_t* dataPtr;
size_t sizeBytes; size_t sizeBytes;
bool markerBit; bool markerBit;
int timesNacked;
FrameType frameType; FrameType frameType;
VideoCodecType codec; 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 // If all packets of the frame is continuous, find the first packet of the
// frame and create an RtpFrameObject. // frame and create an RtpFrameObject.
if (sequence_buffer_[index].frame_end) { 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; 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; 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_index = start_index > 0 ? start_index - 1 : size_ - 1;
start_seq_num--; start_seq_num--;
} }
sequence_buffer_[start_index].frame_created = true;
std::unique_ptr<RtpFrameObject> frame( std::unique_ptr<RtpFrameObject> frame(new RtpFrameObject(
new RtpFrameObject(this, start_seq_num, seq_num)); this, start_seq_num, seq_num, frame_size, max_nack_count));
reference_finder_.ManageFrame(std::move(frame)); reference_finder_.ManageFrame(std::move(frame));
} }

View File

@ -265,12 +265,62 @@ TEST_F(TestPacketBuffer, InsertDuplicatePacket) {
EXPECT_TRUE(packet_buffer_->InsertPacket(packet)); 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) { TEST_F(TestPacketBuffer, ExpandBuffer) {
uint16_t seq_num = Rand(); uint16_t seq_num = Rand();
for (int i = 0; i < kStartSize + 1; ++i) { for (int i = 0; i < kStartSize + 1; ++i) {
// seq_num , kf, frst, lst // seq_num , kf, frst, lst
InsertGeneric(seq_num + i, kT , kT, kT); InsertGeneric(seq_num + i, kT, kT , kT);
} }
} }