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:
@ -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_;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user