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,
|
||||
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_;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -39,6 +39,7 @@ class VCMPacket {
|
||||
const uint8_t* dataPtr;
|
||||
size_t sizeBytes;
|
||||
bool markerBit;
|
||||
int timesNacked;
|
||||
|
||||
FrameType frameType;
|
||||
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
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user