Delete all logic related to VCMDecodeErrorMode

Bug: webrtc:8064
Change-Id: I345f342a314d88390fff8b305b121076b45a51e8
Reviewed-on: https://webrtc-review.googlesource.com/c/116692
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26283}
This commit is contained in:
Niels Möller
2019-01-10 15:35:56 +01:00
committed by Commit Bot
parent 309aafe351
commit 375b346b30
17 changed files with 145 additions and 1011 deletions

View File

@ -46,12 +46,12 @@ TEST(TestDecodingState, FrameContinuity) {
FrameData frame_data; FrameData frame_data;
frame_data.rtt_ms = 0; frame_data.rtt_ms = 0;
frame_data.rolling_average_packets_per_frame = -1; frame_data.rolling_average_packets_per_frame = -1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
// Always start with a key frame. // Always start with a key frame.
dec_state.Reset(); dec_state.Reset();
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
packet.frameType = kVideoFrameKey; packet.frameType = kVideoFrameKey;
EXPECT_LE(0, frame_key.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame_key.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame_key)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame_key));
dec_state.SetState(&frame); dec_state.SetState(&frame);
frame.Reset(); frame.Reset();
@ -59,26 +59,26 @@ TEST(TestDecodingState, FrameContinuity) {
// Use pictureId // Use pictureId
packet.is_first_packet_in_frame = false; packet.is_first_packet_in_frame = false;
vp8_header.pictureId = 0x0002; vp8_header.pictureId = 0x0002;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
frame.Reset(); frame.Reset();
vp8_header.pictureId = 0; vp8_header.pictureId = 0;
packet.seqNum = 10; packet.seqNum = 10;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
// Use sequence numbers. // Use sequence numbers.
vp8_header.pictureId = kNoPictureId; vp8_header.pictureId = kNoPictureId;
frame.Reset(); frame.Reset();
packet.seqNum = dec_state.sequence_num() - 1u; packet.seqNum = dec_state.sequence_num() - 1u;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
frame.Reset(); frame.Reset();
packet.seqNum = dec_state.sequence_num() + 1u; packet.seqNum = dec_state.sequence_num() + 1u;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
// Insert another packet to this frame // Insert another packet to this frame
packet.seqNum++; packet.seqNum++;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
// Verify wrap. // Verify wrap.
EXPECT_LE(dec_state.sequence_num(), 0xffff); EXPECT_LE(dec_state.sequence_num(), 0xffff);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
@ -93,7 +93,7 @@ TEST(TestDecodingState, FrameContinuity) {
packet.seqNum = 1; packet.seqNum = 1;
packet.timestamp = 1; packet.timestamp = 1;
EXPECT_TRUE(dec_state.full_sync()); EXPECT_TRUE(dec_state.full_sync());
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync()); EXPECT_TRUE(dec_state.full_sync());
frame.Reset(); frame.Reset();
@ -103,7 +103,7 @@ TEST(TestDecodingState, FrameContinuity) {
vp8_header.pictureId = 1; vp8_header.pictureId = 1;
packet.seqNum = 2; packet.seqNum = 2;
packet.timestamp = 2; packet.timestamp = 2;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync()); EXPECT_TRUE(dec_state.full_sync());
@ -114,7 +114,7 @@ TEST(TestDecodingState, FrameContinuity) {
vp8_header.pictureId = 3; vp8_header.pictureId = 3;
packet.seqNum = 4; packet.seqNum = 4;
packet.timestamp = 4; packet.timestamp = 4;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
// Now insert the next non-base layer (belonging to a next tl0PicId). // Now insert the next non-base layer (belonging to a next tl0PicId).
frame.Reset(); frame.Reset();
@ -123,7 +123,7 @@ TEST(TestDecodingState, FrameContinuity) {
vp8_header.pictureId = 4; vp8_header.pictureId = 4;
packet.seqNum = 5; packet.seqNum = 5;
packet.timestamp = 5; packet.timestamp = 5;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
// Checking continuity and not updating the state - this should not trigger // Checking continuity and not updating the state - this should not trigger
// an update of sync state. // an update of sync state.
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
@ -135,7 +135,7 @@ TEST(TestDecodingState, FrameContinuity) {
vp8_header.pictureId = 5; vp8_header.pictureId = 5;
packet.seqNum = 6; packet.seqNum = 6;
packet.timestamp = 6; packet.timestamp = 6;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_FALSE(dec_state.full_sync()); EXPECT_FALSE(dec_state.full_sync());
@ -147,7 +147,7 @@ TEST(TestDecodingState, FrameContinuity) {
vp8_header.pictureId = 6; vp8_header.pictureId = 6;
packet.seqNum = 7; packet.seqNum = 7;
packet.timestamp = 7; packet.timestamp = 7;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_FALSE(dec_state.full_sync()); EXPECT_FALSE(dec_state.full_sync());
frame.Reset(); frame.Reset();
@ -156,7 +156,7 @@ TEST(TestDecodingState, FrameContinuity) {
vp8_header.pictureId = 7; vp8_header.pictureId = 7;
packet.seqNum = 8; packet.seqNum = 8;
packet.timestamp = 8; packet.timestamp = 8;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
// The current frame is not continuous // The current frame is not continuous
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -175,7 +175,7 @@ TEST(TestDecodingState, UpdateOldPacket) {
FrameData frame_data; FrameData frame_data;
frame_data.rtt_ms = 0; frame_data.rtt_ms = 0;
frame_data.rolling_average_packets_per_frame = -1; frame_data.rolling_average_packets_per_frame = -1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_EQ(dec_state.sequence_num(), 1); EXPECT_EQ(dec_state.sequence_num(), 1);
// Insert an empty packet that does not belong to the same frame. // Insert an empty packet that does not belong to the same frame.
@ -227,7 +227,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
FrameData frame_data; FrameData frame_data;
frame_data.rtt_ms = 0; frame_data.rtt_ms = 0;
frame_data.rolling_average_packets_per_frame = -1; frame_data.rolling_average_packets_per_frame = -1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
dec_state.SetState(&frame); dec_state.SetState(&frame);
// tl0PicIdx 0, temporal id 1. // tl0PicIdx 0, temporal id 1.
frame.Reset(); frame.Reset();
@ -236,7 +236,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
vp8_header.tl0PicIdx = 0; vp8_header.tl0PicIdx = 0;
vp8_header.temporalIdx = 1; vp8_header.temporalIdx = 1;
vp8_header.pictureId = 1; vp8_header.pictureId = 1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync()); EXPECT_TRUE(dec_state.full_sync());
@ -248,7 +248,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
vp8_header.tl0PicIdx = 0; vp8_header.tl0PicIdx = 0;
vp8_header.temporalIdx = 3; vp8_header.temporalIdx = 3;
vp8_header.pictureId = 3; vp8_header.pictureId = 3;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_FALSE(dec_state.full_sync()); EXPECT_FALSE(dec_state.full_sync());
@ -259,7 +259,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
vp8_header.tl0PicIdx = 1; vp8_header.tl0PicIdx = 1;
vp8_header.temporalIdx = 0; vp8_header.temporalIdx = 0;
vp8_header.pictureId = 4; vp8_header.pictureId = 4;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_FALSE(dec_state.full_sync()); EXPECT_FALSE(dec_state.full_sync());
@ -273,7 +273,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
vp8_header.tl0PicIdx = 2; vp8_header.tl0PicIdx = 2;
vp8_header.temporalIdx = 0; vp8_header.temporalIdx = 0;
vp8_header.pictureId = 5; vp8_header.pictureId = 5;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync()); EXPECT_TRUE(dec_state.full_sync());
@ -286,7 +286,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
vp8_header.tl0PicIdx = 3; vp8_header.tl0PicIdx = 3;
vp8_header.temporalIdx = 0; vp8_header.temporalIdx = 0;
vp8_header.pictureId = 6; vp8_header.pictureId = 6;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
EXPECT_TRUE(dec_state.full_sync()); EXPECT_TRUE(dec_state.full_sync());
frame.Reset(); frame.Reset();
@ -297,7 +297,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
vp8_header.tl0PicIdx = 4; vp8_header.tl0PicIdx = 4;
vp8_header.temporalIdx = 0; vp8_header.temporalIdx = 0;
vp8_header.pictureId = 8; vp8_header.pictureId = 8;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
EXPECT_TRUE(dec_state.full_sync()); EXPECT_TRUE(dec_state.full_sync());
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -313,7 +313,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
vp8_header.temporalIdx = 2; vp8_header.temporalIdx = 2;
vp8_header.pictureId = 9; vp8_header.pictureId = 9;
vp8_header.layerSync = true; vp8_header.layerSync = true;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync()); EXPECT_TRUE(dec_state.full_sync());
@ -334,7 +334,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
vp8_header.temporalIdx = 0; vp8_header.temporalIdx = 0;
vp8_header.pictureId = 0; vp8_header.pictureId = 0;
vp8_header.layerSync = false; vp8_header.layerSync = false;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync()); EXPECT_TRUE(dec_state.full_sync());
// Layer 2 - 2 packets (insert one, lose one). // Layer 2 - 2 packets (insert one, lose one).
@ -348,7 +348,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
vp8_header.temporalIdx = 2; vp8_header.temporalIdx = 2;
vp8_header.pictureId = 1; vp8_header.pictureId = 1;
vp8_header.layerSync = true; vp8_header.layerSync = true;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
// Layer 1 // Layer 1
frame.Reset(); frame.Reset();
@ -361,7 +361,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
vp8_header.temporalIdx = 1; vp8_header.temporalIdx = 1;
vp8_header.pictureId = 2; vp8_header.pictureId = 2;
vp8_header.layerSync = true; vp8_header.layerSync = true;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
EXPECT_TRUE(dec_state.full_sync()); EXPECT_TRUE(dec_state.full_sync());
} }
@ -383,7 +383,7 @@ TEST(TestDecodingState, DiscontinuousPicIdContinuousSeqNum) {
FrameData frame_data; FrameData frame_data;
frame_data.rtt_ms = 0; frame_data.rtt_ms = 0;
frame_data.rolling_average_packets_per_frame = -1; frame_data.rolling_average_packets_per_frame = -1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync()); EXPECT_TRUE(dec_state.full_sync());
@ -395,7 +395,7 @@ TEST(TestDecodingState, DiscontinuousPicIdContinuousSeqNum) {
++packet.seqNum; ++packet.seqNum;
vp8_header.temporalIdx = 1; vp8_header.temporalIdx = 1;
vp8_header.pictureId = 2; vp8_header.pictureId = 2;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
EXPECT_FALSE(dec_state.full_sync()); EXPECT_FALSE(dec_state.full_sync());
@ -412,13 +412,13 @@ TEST(TestDecodingState, OldInput) {
FrameData frame_data; FrameData frame_data;
frame_data.rtt_ms = 0; frame_data.rtt_ms = 0;
frame_data.rolling_average_packets_per_frame = -1; frame_data.rolling_average_packets_per_frame = -1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
dec_state.SetState(&frame); dec_state.SetState(&frame);
packet.timestamp = 9; packet.timestamp = 9;
EXPECT_TRUE(dec_state.IsOldPacket(&packet)); EXPECT_TRUE(dec_state.IsOldPacket(&packet));
// Check for old frame // Check for old frame
frame.Reset(); frame.Reset();
frame.InsertPacket(packet, 0, kNoErrors, frame_data); frame.InsertPacket(packet, 0, frame_data);
EXPECT_TRUE(dec_state.IsOldFrame(&frame)); EXPECT_TRUE(dec_state.IsOldFrame(&frame));
} }
@ -438,7 +438,7 @@ TEST(TestDecodingState, PictureIdRepeat) {
FrameData frame_data; FrameData frame_data;
frame_data.rtt_ms = 0; frame_data.rtt_ms = 0;
frame_data.rolling_average_packets_per_frame = -1; frame_data.rolling_average_packets_per_frame = -1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
dec_state.SetState(&frame); dec_state.SetState(&frame);
// tl0PicIdx 0, temporal id 1. // tl0PicIdx 0, temporal id 1.
frame.Reset(); frame.Reset();
@ -446,14 +446,14 @@ TEST(TestDecodingState, PictureIdRepeat) {
++packet.seqNum; ++packet.seqNum;
vp8_header.temporalIdx++; vp8_header.temporalIdx++;
vp8_header.pictureId++; vp8_header.pictureId++;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
frame.Reset(); frame.Reset();
// Testing only gap in tl0PicIdx when tl0PicIdx in continuous. // Testing only gap in tl0PicIdx when tl0PicIdx in continuous.
vp8_header.tl0PicIdx += 3; vp8_header.tl0PicIdx += 3;
vp8_header.temporalIdx++; vp8_header.temporalIdx++;
vp8_header.tl0PicIdx = 1; vp8_header.tl0PicIdx = 1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
} }
@ -480,14 +480,14 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeKeyFrame) {
// Key frame as first frame // Key frame as first frame
packet.frameType = kVideoFrameKey; packet.frameType = kVideoFrameKey;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
// Key frame again // Key frame again
vp9_hdr.picture_id = 11; vp9_hdr.picture_id = 11;
frame.Reset(); frame.Reset();
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -497,7 +497,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeKeyFrame) {
vp9_hdr.picture_id = 12; vp9_hdr.picture_id = 12;
vp9_hdr.num_ref_pics = 1; vp9_hdr.num_ref_pics = 1;
vp9_hdr.pid_diff[0] = 1; vp9_hdr.pid_diff[0] = 1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
} }
@ -524,7 +524,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeOutOfOrderFrames) {
// Key frame as first frame // Key frame as first frame
packet.frameType = kVideoFrameKey; packet.frameType = kVideoFrameKey;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -534,7 +534,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeOutOfOrderFrames) {
vp9_hdr.picture_id = 15; vp9_hdr.picture_id = 15;
vp9_hdr.num_ref_pics = 1; vp9_hdr.num_ref_pics = 1;
vp9_hdr.pid_diff[0] = 5; vp9_hdr.pid_diff[0] = 5;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -542,7 +542,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeOutOfOrderFrames) {
frame.Reset(); frame.Reset();
vp9_hdr.picture_id = 12; vp9_hdr.picture_id = 12;
vp9_hdr.pid_diff[0] = 2; vp9_hdr.pid_diff[0] = 2;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -553,7 +553,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeOutOfOrderFrames) {
vp9_hdr.pid_diff[0] = 10; vp9_hdr.pid_diff[0] = 10;
vp9_hdr.pid_diff[1] = 8; vp9_hdr.pid_diff[1] = 8;
vp9_hdr.pid_diff[2] = 5; vp9_hdr.pid_diff[2] = 5;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
} }
@ -580,40 +580,40 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
// Key frame as first frame // Key frame as first frame
packet.frameType = kVideoFrameKey; packet.frameType = kVideoFrameKey;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
// Delta frame as first frame // Delta frame as first frame
frame.Reset(); frame.Reset();
packet.frameType = kVideoFrameDelta; packet.frameType = kVideoFrameDelta;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
// Key frame then delta frame // Key frame then delta frame
frame.Reset(); frame.Reset();
packet.frameType = kVideoFrameKey; packet.frameType = kVideoFrameKey;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
dec_state.SetState(&frame); dec_state.SetState(&frame);
frame.Reset(); frame.Reset();
packet.frameType = kVideoFrameDelta; packet.frameType = kVideoFrameDelta;
vp9_hdr.num_ref_pics = 1; vp9_hdr.num_ref_pics = 1;
vp9_hdr.picture_id = 15; vp9_hdr.picture_id = 15;
vp9_hdr.pid_diff[0] = 5; vp9_hdr.pid_diff[0] = 5;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
// Ref to 11, not continuous // Ref to 11, not continuous
frame.Reset(); frame.Reset();
vp9_hdr.picture_id = 16; vp9_hdr.picture_id = 16;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
// Ref to 15, continuous // Ref to 15, continuous
frame.Reset(); frame.Reset();
vp9_hdr.picture_id = 16; vp9_hdr.picture_id = 16;
vp9_hdr.pid_diff[0] = 1; vp9_hdr.pid_diff[0] = 1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -623,7 +623,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
vp9_hdr.num_ref_pics = 2; vp9_hdr.num_ref_pics = 2;
vp9_hdr.pid_diff[0] = 9; vp9_hdr.pid_diff[0] = 9;
vp9_hdr.pid_diff[1] = 5; vp9_hdr.pid_diff[1] = 5;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
// Ref to 10, 15 and 16, continuous // Ref to 10, 15 and 16, continuous
@ -633,7 +633,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
vp9_hdr.pid_diff[0] = 12; vp9_hdr.pid_diff[0] = 12;
vp9_hdr.pid_diff[1] = 7; vp9_hdr.pid_diff[1] = 7;
vp9_hdr.pid_diff[2] = 6; vp9_hdr.pid_diff[2] = 6;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -642,7 +642,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
packet.frameType = kVideoFrameKey; packet.frameType = kVideoFrameKey;
vp9_hdr.picture_id = VCMDecodingState::kFrameDecodedLength - 2; vp9_hdr.picture_id = VCMDecodingState::kFrameDecodedLength - 2;
vp9_hdr.num_ref_pics = 0; vp9_hdr.num_ref_pics = 0;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -652,7 +652,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
vp9_hdr.picture_id = VCMDecodingState::kFrameDecodedLength - 1; vp9_hdr.picture_id = VCMDecodingState::kFrameDecodedLength - 1;
vp9_hdr.num_ref_pics = 1; vp9_hdr.num_ref_pics = 1;
vp9_hdr.pid_diff[0] = 1; vp9_hdr.pid_diff[0] = 1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -661,7 +661,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
vp9_hdr.picture_id = 0; vp9_hdr.picture_id = 0;
vp9_hdr.num_ref_pics = 1; vp9_hdr.num_ref_pics = 1;
vp9_hdr.pid_diff[0] = 1; vp9_hdr.pid_diff[0] = 1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -670,7 +670,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
vp9_hdr.picture_id = 20; vp9_hdr.picture_id = 20;
vp9_hdr.num_ref_pics = 1; vp9_hdr.num_ref_pics = 1;
vp9_hdr.pid_diff[0] = 20; vp9_hdr.pid_diff[0] = 20;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -679,7 +679,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
vp9_hdr.picture_id = 23; vp9_hdr.picture_id = 23;
vp9_hdr.num_ref_pics = 1; vp9_hdr.num_ref_pics = 1;
vp9_hdr.pid_diff[0] = 13; vp9_hdr.pid_diff[0] = 13;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
// Key frame, continuous // Key frame, continuous
@ -687,7 +687,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
packet.frameType = kVideoFrameKey; packet.frameType = kVideoFrameKey;
vp9_hdr.picture_id = 25; vp9_hdr.picture_id = 25;
vp9_hdr.num_ref_pics = 0; vp9_hdr.num_ref_pics = 0;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -697,7 +697,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
vp9_hdr.picture_id = 26; vp9_hdr.picture_id = 26;
vp9_hdr.num_ref_pics = 1; vp9_hdr.num_ref_pics = 1;
vp9_hdr.pid_diff[0] = 1; vp9_hdr.pid_diff[0] = 1;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_TRUE(dec_state.ContinuousFrame(&frame)); EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame); dec_state.SetState(&frame);
@ -706,7 +706,7 @@ TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
vp9_hdr.picture_id = 30; vp9_hdr.picture_id = 30;
vp9_hdr.num_ref_pics = 1; vp9_hdr.num_ref_pics = 1;
vp9_hdr.pid_diff[0] = 30; vp9_hdr.pid_diff[0] = 30;
EXPECT_LE(0, frame.InsertPacket(packet, 0, kNoErrors, frame_data)); EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
EXPECT_FALSE(dec_state.ContinuousFrame(&frame)); EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
} }

View File

@ -80,7 +80,6 @@ bool VCMFrameBuffer::IsSessionComplete() const {
VCMFrameBufferEnum VCMFrameBuffer::InsertPacket( VCMFrameBufferEnum VCMFrameBuffer::InsertPacket(
const VCMPacket& packet, const VCMPacket& packet,
int64_t timeInMs, int64_t timeInMs,
VCMDecodeErrorMode decode_error_mode,
const FrameData& frame_data) { const FrameData& frame_data) {
TRACE_EVENT0("webrtc", "VCMFrameBuffer::InsertPacket"); TRACE_EVENT0("webrtc", "VCMFrameBuffer::InsertPacket");
assert(!(NULL == packet.dataPtr && packet.sizeBytes > 0)); assert(!(NULL == packet.dataPtr && packet.sizeBytes > 0));
@ -129,8 +128,7 @@ VCMFrameBufferEnum VCMFrameBuffer::InsertPacket(
if (packet.sizeBytes > 0) if (packet.sizeBytes > 0)
CopyCodecSpecific(&packet.video_header); CopyCodecSpecific(&packet.video_header);
int retVal = int retVal = _sessionInfo.InsertPacket(packet, _buffer, frame_data);
_sessionInfo.InsertPacket(packet, _buffer, decode_error_mode, frame_data);
if (retVal == -1) { if (retVal == -1) {
return kSizeError; return kSizeError;
} else if (retVal == -2) { } else if (retVal == -2) {
@ -182,9 +180,6 @@ VCMFrameBufferEnum VCMFrameBuffer::InsertPacket(
if (_sessionInfo.complete()) { if (_sessionInfo.complete()) {
SetState(kStateComplete); SetState(kStateComplete);
return kCompleteSession; return kCompleteSession;
} else if (_sessionInfo.decodable()) {
SetState(kStateDecodable);
return kDecodableSession;
} }
return kIncomplete; return kIncomplete;
} }
@ -240,8 +235,7 @@ void VCMFrameBuffer::SetState(VCMFrameBufferStateEnum state) {
break; break;
case kStateComplete: case kStateComplete:
assert(_state == kStateEmpty || _state == kStateIncomplete || assert(_state == kStateEmpty || _state == kStateIncomplete);
_state == kStateDecodable);
break; break;
@ -249,10 +243,6 @@ void VCMFrameBuffer::SetState(VCMFrameBufferStateEnum state) {
// Should only be set to empty through Reset(). // Should only be set to empty through Reset().
assert(false); assert(false);
break; break;
case kStateDecodable:
assert(_state == kStateEmpty || _state == kStateIncomplete);
break;
} }
_state = state; _state = state;
} }

View File

@ -35,7 +35,6 @@ class VCMFrameBuffer : public VCMEncodedFrame {
VCMFrameBufferEnum InsertPacket(const VCMPacket& packet, VCMFrameBufferEnum InsertPacket(const VCMPacket& packet,
int64_t timeInMs, int64_t timeInMs,
VCMDecodeErrorMode decode_error_mode,
const FrameData& frame_data); const FrameData& frame_data);
// State // State

View File

@ -27,19 +27,6 @@ class VideoDecoder;
class VideoEncoder; class VideoEncoder;
struct CodecSpecificInfo; struct CodecSpecificInfo;
// Used to indicate which decode with errors mode should be used.
enum VCMDecodeErrorMode {
kNoErrors, // Never decode with errors. Video will freeze
// if nack is disabled.
kSelectiveErrors, // Frames that are determined decodable in
// VCMSessionInfo may be decoded with missing
// packets. As not all incomplete frames will be
// decodable, video will freeze if nack is disabled.
kWithErrors // Release frames as needed. Errors may be
// introduced as some encoded frames may not be
// complete.
};
class VideoCodingModule : public Module { class VideoCodingModule : public Module {
public: public:
enum SenderNackMode { kNackNone, kNackAll, kNackSelective }; enum SenderNackMode { kNackNone, kNackAll, kNackSelective };
@ -166,12 +153,7 @@ class VideoCodingModule : public Module {
// Return value : VCM_OK, on success; // Return value : VCM_OK, on success;
// < 0, on error. // < 0, on error.
enum ReceiverRobustness { kNone, kHardNack }; enum ReceiverRobustness { kNone, kHardNack };
virtual int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode, virtual int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode) = 0;
VCMDecodeErrorMode errorMode) = 0;
int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode) {
return SetReceiverRobustnessMode(robustnessMode, kNoErrors);
}
// Sets the maximum number of sequence numbers that we are allowed to NACK // Sets the maximum number of sequence numbers that we are allowed to NACK
// and the oldest sequence number that we will consider to NACK. If a // and the oldest sequence number that we will consider to NACK. If a

View File

@ -255,7 +255,6 @@ VCMJitterBuffer::VCMJitterBuffer(Clock* clock,
max_nack_list_size_(0), max_nack_list_size_(0),
max_packet_age_to_nack_(0), max_packet_age_to_nack_(0),
max_incomplete_time_ms_(0), max_incomplete_time_ms_(0),
decode_error_mode_(kNoErrors),
average_packets_per_frame_(0.0f), average_packets_per_frame_(0.0f),
frame_counter_(0) { frame_counter_(0) {
for (int i = 0; i < kStartNumberOfFrames; i++) for (int i = 0; i < kStartNumberOfFrames; i++)
@ -494,43 +493,6 @@ VCMEncodedFrame* VCMJitterBuffer::NextCompleteFrame(uint32_t max_wait_time_ms) {
return encoded_frame; return encoded_frame;
} }
bool VCMJitterBuffer::NextMaybeIncompleteTimestamp(uint32_t* timestamp) {
rtc::CritScope cs(&crit_sect_);
if (!running_) {
return false;
}
if (decode_error_mode_ == kNoErrors) {
// No point to continue, as we are not decoding with errors.
return false;
}
CleanUpOldOrEmptyFrames();
VCMFrameBuffer* oldest_frame;
if (decodable_frames_.empty()) {
if (nack_mode_ != kNoNack || incomplete_frames_.size() <= 1) {
return false;
}
oldest_frame = incomplete_frames_.Front();
// Frame will only be removed from buffer if it is complete (or decodable).
if (oldest_frame->GetState() < kStateComplete) {
return false;
}
} else {
oldest_frame = decodable_frames_.Front();
// If we have exactly one frame in the buffer, release it only if it is
// complete. We know decodable_frames_ is not empty due to the previous
// check.
if (decodable_frames_.size() == 1 && incomplete_frames_.empty() &&
oldest_frame->GetState() != kStateComplete) {
return false;
}
}
*timestamp = oldest_frame->Timestamp();
return true;
}
VCMEncodedFrame* VCMJitterBuffer::ExtractAndSetDecode(uint32_t timestamp) { VCMEncodedFrame* VCMJitterBuffer::ExtractAndSetDecode(uint32_t timestamp) {
rtc::CritScope cs(&crit_sect_); rtc::CritScope cs(&crit_sect_);
if (!running_) { if (!running_) {
@ -711,7 +673,7 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
frame_data.rtt_ms = rtt_ms_; frame_data.rtt_ms = rtt_ms_;
frame_data.rolling_average_packets_per_frame = average_packets_per_frame_; frame_data.rolling_average_packets_per_frame = average_packets_per_frame_;
VCMFrameBufferEnum buffer_state = VCMFrameBufferEnum buffer_state =
frame->InsertPacket(packet, now_ms, decode_error_mode_, frame_data); frame->InsertPacket(packet, now_ms, frame_data);
if (previous_state != kStateComplete) { if (previous_state != kStateComplete) {
TRACE_EVENT_ASYNC_BEGIN1("webrtc", "Video", frame->Timestamp(), "timestamp", TRACE_EVENT_ASYNC_BEGIN1("webrtc", "Video", frame->Timestamp(), "timestamp",
@ -747,18 +709,14 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
break; break;
} }
case kCompleteSession: { case kCompleteSession: {
if (previous_state != kStateDecodable && if (previous_state != kStateComplete) {
previous_state != kStateComplete) {
CountFrame(*frame); CountFrame(*frame);
if (continuous) { if (continuous) {
// Signal that we have a complete session. // Signal that we have a complete session.
frame_event_->Set(); frame_event_->Set();
} }
} }
RTC_FALLTHROUGH();
}
// Note: There is no break here - continuing to kDecodableSession.
case kDecodableSession: {
*retransmitted = (frame->GetNackCount() > 0); *retransmitted = (frame->GetNackCount() > 0);
if (continuous) { if (continuous) {
decodable_frames_.InsertFrame(frame); decodable_frames_.InsertFrame(frame);
@ -812,12 +770,8 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
bool VCMJitterBuffer::IsContinuousInState( bool VCMJitterBuffer::IsContinuousInState(
const VCMFrameBuffer& frame, const VCMFrameBuffer& frame,
const VCMDecodingState& decoding_state) const { const VCMDecodingState& decoding_state) const {
// Is this frame (complete or decodable) and continuous? // Is this frame complete and continuous?
// kStateDecodable will never be set when decode_error_mode_ is false return (frame.GetState() == kStateComplete) &&
// as SessionInfo determines this state based on the error mode (and frame
// completeness).
return (frame.GetState() == kStateComplete ||
frame.GetState() == kStateDecodable) &&
decoding_state.ContinuousFrame(&frame); decoding_state.ContinuousFrame(&frame);
} }
@ -1024,11 +978,6 @@ std::vector<uint16_t> VCMJitterBuffer::GetNackList(bool* request_key_frame) {
return nack_list; return nack_list;
} }
void VCMJitterBuffer::SetDecodeErrorMode(VCMDecodeErrorMode error_mode) {
rtc::CritScope cs(&crit_sect_);
decode_error_mode_ = error_mode;
}
VCMFrameBuffer* VCMJitterBuffer::NextFrame() const { VCMFrameBuffer* VCMJitterBuffer::NextFrame() const {
if (!decodable_frames_.empty()) if (!decodable_frames_.empty())
return decodable_frames_.Front(); return decodable_frames_.Front();

View File

@ -145,11 +145,6 @@ class VCMJitterBuffer {
// If found, a pointer to the frame is returned. Returns nullptr otherwise. // If found, a pointer to the frame is returned. Returns nullptr otherwise.
VCMEncodedFrame* NextCompleteFrame(uint32_t max_wait_time_ms); VCMEncodedFrame* NextCompleteFrame(uint32_t max_wait_time_ms);
// Locates a frame for decoding (even an incomplete) without delay.
// The function returns true once such a frame is found, its corresponding
// timestamp is returned. Otherwise, returns false.
bool NextMaybeIncompleteTimestamp(uint32_t* timestamp);
// Extract frame corresponding to input timestamp. // Extract frame corresponding to input timestamp.
// Frame will be set to a decoding state. // Frame will be set to a decoding state.
VCMEncodedFrame* ExtractAndSetDecode(uint32_t timestamp); VCMEncodedFrame* ExtractAndSetDecode(uint32_t timestamp);
@ -195,11 +190,6 @@ class VCMJitterBuffer {
// Returns a list of the sequence numbers currently missing. // Returns a list of the sequence numbers currently missing.
std::vector<uint16_t> GetNackList(bool* request_key_frame); std::vector<uint16_t> GetNackList(bool* request_key_frame);
// Set decode error mode - Should not be changed in the middle of the
// session. Changes will not influence frames already in the buffer.
void SetDecodeErrorMode(VCMDecodeErrorMode error_mode);
VCMDecodeErrorMode decode_error_mode() const { return decode_error_mode_; }
void RegisterStatsCallback(VCMReceiveStatisticsCallback* callback); void RegisterStatsCallback(VCMReceiveStatisticsCallback* callback);
private: private:
@ -367,7 +357,6 @@ class VCMJitterBuffer {
int max_packet_age_to_nack_; // Measured in sequence numbers. int max_packet_age_to_nack_; // Measured in sequence numbers.
int max_incomplete_time_ms_; int max_incomplete_time_ms_;
VCMDecodeErrorMode decode_error_mode_;
// Estimated rolling average of packets per frame // Estimated rolling average of packets per frame
float average_packets_per_frame_; float average_packets_per_frame_;
// average_packets_per_frame converges fast if we have fewer than this many // average_packets_per_frame converges fast if we have fewer than this many

View File

@ -44,7 +44,6 @@ enum VCMFrameBufferEnum {
kNoError = 0, kNoError = 0,
kIncomplete = 1, // Frame incomplete. kIncomplete = 1, // Frame incomplete.
kCompleteSession = 3, // at least one layer in the frame complete. kCompleteSession = 3, // at least one layer in the frame complete.
kDecodableSession = 4, // Frame incomplete, but ready to be decoded
kDuplicatePacket = 5 // We're receiving a duplicate packet. kDuplicatePacket = 5 // We're receiving a duplicate packet.
}; };
@ -52,7 +51,6 @@ enum VCMFrameBufferStateEnum {
kStateEmpty, // frame popped by the RTP receiver kStateEmpty, // frame popped by the RTP receiver
kStateIncomplete, // frame that have one or more packet(s) stored kStateIncomplete, // frame that have one or more packet(s) stored
kStateComplete, // frame that have all packets kStateComplete, // frame that have all packets
kStateDecodable // Hybrid mode - frame can be decoded
}; };
enum { kH264StartCodeLengthBytes = 4 }; enum { kH264StartCodeLengthBytes = 4 };

View File

@ -258,15 +258,6 @@ class TestBasicJitterBuffer : public ::testing::TestWithParam<std::string>,
return jitter_buffer_->ExtractAndSetDecode(found_frame->Timestamp()); return jitter_buffer_->ExtractAndSetDecode(found_frame->Timestamp());
} }
VCMEncodedFrame* DecodeIncompleteFrame() {
uint32_t timestamp = 0;
bool found_frame = jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp);
if (!found_frame)
return NULL;
VCMEncodedFrame* frame = jitter_buffer_->ExtractAndSetDecode(timestamp);
return frame;
}
void CheckOutFrame(VCMEncodedFrame* frame_out, void CheckOutFrame(VCMEncodedFrame* frame_out,
unsigned int size, unsigned int size,
bool startCode) { bool startCode) {
@ -413,17 +404,6 @@ class TestRunningJitterBuffer : public ::testing::TestWithParam<std::string>,
return ret; return ret;
} }
bool DecodeIncompleteFrame() {
uint32_t timestamp = 0;
bool found_frame = jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp);
if (!found_frame)
return false;
VCMEncodedFrame* frame = jitter_buffer_->ExtractAndSetDecode(timestamp);
bool ret = (frame != NULL);
jitter_buffer_->ReleaseFrame(frame);
return ret;
}
VCMJitterBuffer* jitter_buffer_; VCMJitterBuffer* jitter_buffer_;
StreamGenerator* stream_generator_; StreamGenerator* stream_generator_;
std::unique_ptr<SimulatedClock> clock_; std::unique_ptr<SimulatedClock> clock_;
@ -446,26 +426,14 @@ class TestJitterBufferNack : public TestRunningJitterBuffer {
TEST_F(TestBasicJitterBuffer, StopRunning) { TEST_F(TestBasicJitterBuffer, StopRunning) {
jitter_buffer_->Stop(); jitter_buffer_->Stop();
EXPECT_TRUE(NULL == DecodeCompleteFrame()); EXPECT_TRUE(NULL == DecodeCompleteFrame());
EXPECT_TRUE(NULL == DecodeIncompleteFrame());
jitter_buffer_->Start(); jitter_buffer_->Start();
// Allow selective errors.
jitter_buffer_->SetDecodeErrorMode(kSelectiveErrors);
// No packets inserted. // No packets inserted.
EXPECT_TRUE(NULL == DecodeCompleteFrame()); EXPECT_TRUE(NULL == DecodeCompleteFrame());
EXPECT_TRUE(NULL == DecodeIncompleteFrame());
// Allow decoding with errors.
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
// No packets inserted.
EXPECT_TRUE(NULL == DecodeCompleteFrame());
EXPECT_TRUE(NULL == DecodeIncompleteFrame());
} }
TEST_F(TestBasicJitterBuffer, SinglePacketFrame) { TEST_F(TestBasicJitterBuffer, SinglePacketFrame) {
// Always start with a complete key frame when not allowing errors. // Always start with a complete key frame when not allowing errors.
jitter_buffer_->SetDecodeErrorMode(kNoErrors);
packet_->frameType = kVideoFrameKey; packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true; packet_->is_first_packet_in_frame = true;
packet_->markerBit = true; packet_->markerBit = true;
@ -484,7 +452,6 @@ TEST_F(TestBasicJitterBuffer, SinglePacketFrame) {
TEST_F(TestBasicJitterBuffer, VerifyHistogramStats) { TEST_F(TestBasicJitterBuffer, VerifyHistogramStats) {
metrics::Reset(); metrics::Reset();
// Always start with a complete key frame when not allowing errors. // Always start with a complete key frame when not allowing errors.
jitter_buffer_->SetDecodeErrorMode(kNoErrors);
packet_->frameType = kVideoFrameKey; packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true; packet_->is_first_packet_in_frame = true;
packet_->markerBit = true; packet_->markerBit = true;
@ -864,7 +831,6 @@ TEST_F(TestBasicJitterBuffer, DuplicatePreviousDeltaFramePacket) {
packet_->markerBit = true; packet_->markerBit = true;
packet_->seqNum = seq_num_; packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_; packet_->timestamp = timestamp_;
jitter_buffer_->SetDecodeErrorMode(kNoErrors);
EXPECT_EQ(0, jitter_buffer_->num_packets()); EXPECT_EQ(0, jitter_buffer_->num_packets());
EXPECT_EQ(0, jitter_buffer_->num_duplicated_packets()); EXPECT_EQ(0, jitter_buffer_->num_duplicated_packets());
@ -1162,8 +1128,6 @@ TEST_F(TestBasicJitterBuffer, H264InsertStartCode) {
} }
TEST_F(TestBasicJitterBuffer, SpsAndPpsHandling) { TEST_F(TestBasicJitterBuffer, SpsAndPpsHandling) {
jitter_buffer_->SetDecodeErrorMode(kNoErrors);
auto& h264_header = auto& h264_header =
packet_->video_header.video_type_header.emplace<RTPVideoHeaderH264>(); packet_->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
packet_->timestamp = timestamp_; packet_->timestamp = timestamp_;
@ -1246,364 +1210,6 @@ TEST_F(TestBasicJitterBuffer, SpsAndPpsHandling) {
jitter_buffer_->ReleaseFrame(frame_out); jitter_buffer_->ReleaseFrame(frame_out);
} }
// Test threshold conditions of decodable state.
TEST_F(TestBasicJitterBuffer, PacketLossWithSelectiveErrorsThresholdCheck) {
jitter_buffer_->SetDecodeErrorMode(kSelectiveErrors);
// Always start with a key frame. Use 10 packets to test Decodable State
// boundaries.
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true;
packet_->markerBit = false;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
bool retransmitted = false;
EXPECT_EQ(kIncomplete,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
uint32_t timestamp = 0;
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
packet_->is_first_packet_in_frame = false;
for (int i = 1; i < 9; ++i) {
packet_->seqNum++;
EXPECT_EQ(kIncomplete,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
}
// last packet
packet_->markerBit = true;
packet_->seqNum++;
EXPECT_EQ(kCompleteSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
CheckOutFrame(frame_out, 10 * size_, false);
EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
jitter_buffer_->ReleaseFrame(frame_out);
// An incomplete frame can only be decoded once a subsequent frame has begun
// to arrive. Insert packet in distant frame for this purpose.
packet_->frameType = kVideoFrameDelta;
packet_->is_first_packet_in_frame = true;
packet_->markerBit = false;
packet_->seqNum += 100;
packet_->timestamp += 33 * 90 * 8;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
// Insert second frame
packet_->seqNum -= 99;
packet_->timestamp -= 33 * 90 * 7;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_TRUE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
packet_->is_first_packet_in_frame = false;
for (int i = 1; i < 8; ++i) {
packet_->seqNum++;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_TRUE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
}
packet_->seqNum++;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_TRUE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
frame_out = DecodeIncompleteFrame();
ASSERT_FALSE(NULL == frame_out);
CheckOutFrame(frame_out, 9 * size_, false);
EXPECT_EQ(kVideoFrameDelta, frame_out->FrameType());
jitter_buffer_->ReleaseFrame(frame_out);
packet_->markerBit = true;
packet_->seqNum++;
EXPECT_EQ(kOldPacket, jitter_buffer_->InsertPacket(*packet_, &retransmitted));
}
// Make sure first packet is present before a frame can be decoded.
TEST_F(TestBasicJitterBuffer, PacketLossWithSelectiveErrorsIncompleteKey) {
jitter_buffer_->SetDecodeErrorMode(kSelectiveErrors);
// Always start with a key frame.
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true;
packet_->markerBit = true;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
bool retransmitted = false;
EXPECT_EQ(kCompleteSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
CheckOutFrame(frame_out, size_, false);
EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
jitter_buffer_->ReleaseFrame(frame_out);
// An incomplete frame can only be decoded once a subsequent frame has begun
// to arrive. Insert packet in distant frame for this purpose.
packet_->frameType = kVideoFrameDelta;
packet_->is_first_packet_in_frame = false;
packet_->markerBit = false;
packet_->seqNum += 100;
packet_->timestamp += 33 * 90 * 8;
EXPECT_EQ(kIncomplete,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
uint32_t timestamp;
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
// Insert second frame - an incomplete key frame.
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true;
packet_->seqNum -= 99;
packet_->timestamp -= 33 * 90 * 7;
EXPECT_EQ(kIncomplete,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
// Insert a few more packets. Make sure we're waiting for the key frame to be
// complete.
packet_->is_first_packet_in_frame = false;
for (int i = 1; i < 5; ++i) {
packet_->seqNum++;
EXPECT_EQ(kIncomplete,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
}
// Complete key frame.
packet_->markerBit = true;
packet_->seqNum++;
EXPECT_EQ(kCompleteSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
frame_out = DecodeCompleteFrame();
CheckOutFrame(frame_out, 6 * size_, false);
EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
jitter_buffer_->ReleaseFrame(frame_out);
}
// Make sure first packet is present before a frame can be decoded.
TEST_F(TestBasicJitterBuffer, PacketLossWithSelectiveErrorsMissingFirstPacket) {
jitter_buffer_->SetDecodeErrorMode(kSelectiveErrors);
// Always start with a key frame.
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true;
packet_->markerBit = true;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
bool retransmitted = false;
EXPECT_EQ(kCompleteSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
CheckOutFrame(frame_out, size_, false);
EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
jitter_buffer_->ReleaseFrame(frame_out);
// An incomplete frame can only be decoded once a subsequent frame has begun
// to arrive. Insert packet in distant frame for this purpose.
packet_->frameType = kVideoFrameDelta;
packet_->is_first_packet_in_frame = false;
packet_->markerBit = false;
packet_->seqNum += 100;
packet_->timestamp += 33 * 90 * 8;
EXPECT_EQ(kIncomplete,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
uint32_t timestamp;
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
// Insert second frame with the first packet missing. Make sure we're waiting
// for the key frame to be complete.
packet_->seqNum -= 98;
packet_->timestamp -= 33 * 90 * 7;
EXPECT_EQ(kIncomplete,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
for (int i = 0; i < 5; ++i) {
packet_->seqNum++;
EXPECT_EQ(kIncomplete,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_FALSE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
}
// Add first packet. Frame should now be decodable, but incomplete.
packet_->is_first_packet_in_frame = true;
packet_->seqNum -= 6;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_TRUE(jitter_buffer_->NextMaybeIncompleteTimestamp(&timestamp));
frame_out = DecodeIncompleteFrame();
CheckOutFrame(frame_out, 7 * size_, false);
EXPECT_EQ(kVideoFrameDelta, frame_out->FrameType());
jitter_buffer_->ReleaseFrame(frame_out);
}
TEST_F(TestBasicJitterBuffer, DiscontinuousStreamWhenDecodingWithErrors) {
// Will use one packet per frame.
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true;
packet_->markerBit = true;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
bool retransmitted = false;
EXPECT_EQ(kCompleteSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
uint32_t next_timestamp;
VCMEncodedFrame* frame = jitter_buffer_->NextCompleteFrame(0);
EXPECT_NE(frame, nullptr);
EXPECT_EQ(packet_->timestamp, frame->Timestamp());
frame = jitter_buffer_->ExtractAndSetDecode(frame->Timestamp());
EXPECT_TRUE(frame != NULL);
jitter_buffer_->ReleaseFrame(frame);
// Drop a complete frame.
timestamp_ += 2 * 33 * 90;
seq_num_ += 2;
packet_->frameType = kVideoFrameDelta;
packet_->is_first_packet_in_frame = true;
packet_->markerBit = false;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
// Insert a packet (so the previous one will be released).
timestamp_ += 33 * 90;
seq_num_ += 2;
packet_->frameType = kVideoFrameDelta;
packet_->is_first_packet_in_frame = true;
packet_->markerBit = false;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(jitter_buffer_->NextCompleteFrame(0), nullptr);
EXPECT_TRUE(jitter_buffer_->NextMaybeIncompleteTimestamp(&next_timestamp));
EXPECT_EQ(packet_->timestamp - 33 * 90, next_timestamp);
}
TEST_F(TestBasicJitterBuffer, PacketLoss) {
// Verify missing packets statistics and not decodable packets statistics.
// Insert 10 frames consisting of 4 packets and remove one from all of them.
// The last packet is an empty (non-media) packet.
// Select a start seqNum which triggers a difficult wrap situation
// The JB will only output (incomplete)frames if the next one has started
// to arrive. Start by inserting one frame (key).
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
seq_num_ = 0xffff - 4;
seq_num_++;
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true;
packet_->markerBit = false;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
packet_->completeNALU = kNaluStart;
bool retransmitted = false;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
for (int i = 0; i < 11; ++i) {
webrtc::FrameType frametype = kVideoFrameDelta;
seq_num_++;
timestamp_ += 33 * 90;
packet_->frameType = frametype;
packet_->is_first_packet_in_frame = true;
packet_->markerBit = false;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
packet_->completeNALU = kNaluStart;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
// Should not be complete.
EXPECT_TRUE(frame_out == NULL);
seq_num_ += 2;
packet_->is_first_packet_in_frame = false;
packet_->markerBit = true;
packet_->seqNum = seq_num_;
packet_->completeNALU = kNaluEnd;
EXPECT_EQ(jitter_buffer_->InsertPacket(*packet_, &retransmitted),
kDecodableSession);
// Insert an empty (non-media) packet.
seq_num_++;
packet_->is_first_packet_in_frame = false;
packet_->markerBit = false;
packet_->seqNum = seq_num_;
packet_->completeNALU = kNaluEnd;
packet_->frameType = kEmptyFrame;
EXPECT_EQ(jitter_buffer_->InsertPacket(*packet_, &retransmitted),
kDecodableSession);
frame_out = DecodeIncompleteFrame();
// One of the packets has been discarded by the jitter buffer.
// Last frame can't be extracted yet.
if (i < 10) {
CheckOutFrame(frame_out, size_, false);
if (i == 0) {
EXPECT_EQ(kVideoFrameKey, frame_out->FrameType());
} else {
EXPECT_EQ(frametype, frame_out->FrameType());
}
EXPECT_FALSE(frame_out->Complete());
EXPECT_FALSE(frame_out->MissingFrame());
}
jitter_buffer_->ReleaseFrame(frame_out);
}
// Insert 3 old packets and verify that we have 3 discarded packets
// Match value to actual latest timestamp decoded.
timestamp_ -= 33 * 90;
packet_->timestamp = timestamp_ - 1000;
EXPECT_EQ(kOldPacket, jitter_buffer_->InsertPacket(*packet_, &retransmitted));
packet_->timestamp = timestamp_ - 500;
EXPECT_EQ(kOldPacket, jitter_buffer_->InsertPacket(*packet_, &retransmitted));
packet_->timestamp = timestamp_ - 100;
EXPECT_EQ(kOldPacket, jitter_buffer_->InsertPacket(*packet_, &retransmitted));
EXPECT_EQ(3, jitter_buffer_->num_discarded_packets());
jitter_buffer_->Flush();
// This statistic shouldn't be reset by a flush.
EXPECT_EQ(3, jitter_buffer_->num_discarded_packets());
}
TEST_F(TestBasicJitterBuffer, DeltaFrame100PacketsWithSeqNumWrap) { TEST_F(TestBasicJitterBuffer, DeltaFrame100PacketsWithSeqNumWrap) {
seq_num_ = 0xfff0; seq_num_ = 0xfff0;
packet_->frameType = kVideoFrameKey; packet_->frameType = kVideoFrameKey;
@ -2016,7 +1622,6 @@ TEST_F(TestBasicJitterBuffer, ExceedNumOfFrameWithSeqNumWrap) {
} }
TEST_F(TestBasicJitterBuffer, EmptyLastFrame) { TEST_F(TestBasicJitterBuffer, EmptyLastFrame) {
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
seq_num_ = 3; seq_num_ = 3;
// Insert one empty packet per frame, should never return the last timestamp // Insert one empty packet per frame, should never return the last timestamp
// inserted. Only return empty frames in the presence of subsequent frames. // inserted. Only return empty frames in the presence of subsequent frames.
@ -2032,204 +1637,13 @@ TEST_F(TestBasicJitterBuffer, EmptyLastFrame) {
packet_->frameType = kEmptyFrame; packet_->frameType = kEmptyFrame;
EXPECT_EQ(kNoError, jitter_buffer_->InsertPacket(*packet_, &retransmitted)); EXPECT_EQ(kNoError, jitter_buffer_->InsertPacket(*packet_, &retransmitted));
VCMEncodedFrame* testFrame = DecodeIncompleteFrame();
// Timestamp should never be the last TS inserted.
if (testFrame != NULL) {
EXPECT_TRUE(testFrame->Timestamp() < timestamp_);
jitter_buffer_->ReleaseFrame(testFrame);
}
} }
} }
TEST_F(TestBasicJitterBuffer, H264IncompleteNalu) {
jitter_buffer_->SetNackMode(kNoNack, -1, -1);
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
++seq_num_;
timestamp_ += 33 * 90;
int insertedLength = 0;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true;
packet_->completeNALU = kNaluStart;
packet_->markerBit = false;
bool retransmitted = false;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
seq_num_ += 2; // Skip one packet.
packet_->seqNum = seq_num_;
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = false;
packet_->completeNALU = kNaluIncomplete;
packet_->markerBit = false;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
seq_num_++;
packet_->seqNum = seq_num_;
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = false;
packet_->completeNALU = kNaluEnd;
packet_->markerBit = false;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
seq_num_++;
packet_->seqNum = seq_num_;
packet_->completeNALU = kNaluComplete;
packet_->markerBit = true; // Last packet.
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
// The JB will only output (incomplete) frames if a packet belonging to a
// subsequent frame was already inserted. Insert one packet of a subsequent
// frame. place high timestamp so the JB would always have a next frame
// (otherwise, for every inserted frame we need to take care of the next
// frame as well).
packet_->seqNum = 1;
packet_->timestamp = timestamp_ + 33 * 90 * 10;
packet_->frameType = kVideoFrameDelta;
packet_->is_first_packet_in_frame = false;
packet_->completeNALU = kNaluStart;
packet_->markerBit = false;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
VCMEncodedFrame* frame_out = DecodeIncompleteFrame();
// We can decode everything from a NALU until a packet has been lost.
// Thus we can decode the first packet of the first NALU and the second NALU
// which consists of one packet.
CheckOutFrame(frame_out, packet_->sizeBytes * 2, false);
jitter_buffer_->ReleaseFrame(frame_out);
// Test reordered start frame + 1 lost.
seq_num_ += 2; // Re-order 1 frame.
timestamp_ += 33 * 90;
insertedLength = 0;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = false;
packet_->completeNALU = kNaluEnd;
packet_->markerBit = false;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
insertedLength += packet_->sizeBytes; // This packet should be decoded.
seq_num_--;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true;
packet_->completeNALU = kNaluStart;
packet_->markerBit = false;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
insertedLength += packet_->sizeBytes; // This packet should be decoded.
seq_num_ += 3; // One packet drop.
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = false;
packet_->completeNALU = kNaluComplete;
packet_->markerBit = false;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
insertedLength += packet_->sizeBytes; // This packet should be decoded.
seq_num_++;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = false;
packet_->completeNALU = kNaluStart;
packet_->markerBit = false;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
// This packet should be decoded since it's the beginning of a NAL.
insertedLength += packet_->sizeBytes;
seq_num_ += 2;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = false;
packet_->completeNALU = kNaluEnd;
packet_->markerBit = true;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
// This packet should not be decoded because it is an incomplete NAL if it
// is the last.
frame_out = DecodeIncompleteFrame();
// Only last NALU is complete.
CheckOutFrame(frame_out, insertedLength, false);
jitter_buffer_->ReleaseFrame(frame_out);
// Test to insert empty packet.
seq_num_++;
timestamp_ += 33 * 90;
WebRtcRTPHeader rtpHeader;
memset(&rtpHeader, 0, sizeof(rtpHeader));
rtpHeader.video_header().codec = kVideoCodecGeneric;
VCMPacket emptypacket(data_, 0, rtpHeader);
emptypacket.seqNum = seq_num_;
emptypacket.timestamp = timestamp_;
emptypacket.frameType = kVideoFrameKey;
emptypacket.is_first_packet_in_frame = true;
emptypacket.completeNALU = kNaluComplete;
emptypacket.markerBit = true;
EXPECT_EQ(kCompleteSession,
jitter_buffer_->InsertPacket(emptypacket, &retransmitted));
// This packet should not be decoded because it is an incomplete NAL if it
// is the last.
// Will be sent to the decoder, as a packet belonging to a subsequent frame
// has arrived.
frame_out = DecodeIncompleteFrame();
EXPECT_TRUE(frame_out != NULL);
jitter_buffer_->ReleaseFrame(frame_out);
// Test that a frame can include an empty packet.
seq_num_++;
timestamp_ += 33 * 90;
packet_->seqNum = seq_num_;
packet_->timestamp = timestamp_;
packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true;
packet_->completeNALU = kNaluComplete;
packet_->markerBit = false;
EXPECT_EQ(kDecodableSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
seq_num_++;
emptypacket.seqNum = seq_num_;
emptypacket.timestamp = timestamp_;
emptypacket.frameType = kVideoFrameKey;
emptypacket.is_first_packet_in_frame = true;
emptypacket.completeNALU = kNaluComplete;
emptypacket.markerBit = true;
EXPECT_EQ(kCompleteSession,
jitter_buffer_->InsertPacket(emptypacket, &retransmitted));
frame_out = DecodeCompleteFrame();
// Only last NALU is complete
CheckOutFrame(frame_out, packet_->sizeBytes, false);
jitter_buffer_->ReleaseFrame(frame_out);
}
TEST_F(TestBasicJitterBuffer, NextFrameWhenIncomplete) { TEST_F(TestBasicJitterBuffer, NextFrameWhenIncomplete) {
// Test that a we cannot get incomplete frames from the JB if we haven't // Test that a we cannot get incomplete frames from the JB if we haven't
// received the marker bit, unless we have received a packet from a later // received the marker bit, unless we have received a packet from a later
// timestamp. // timestamp.
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
// Start with a complete key frame - insert and decode. // Start with a complete key frame - insert and decode.
packet_->frameType = kVideoFrameKey; packet_->frameType = kVideoFrameKey;
packet_->is_first_packet_in_frame = true; packet_->is_first_packet_in_frame = true;
@ -2248,22 +1662,15 @@ TEST_F(TestBasicJitterBuffer, NextFrameWhenIncomplete) {
packet_->is_first_packet_in_frame = false; packet_->is_first_packet_in_frame = false;
packet_->markerBit = false; packet_->markerBit = false;
EXPECT_EQ(kDecodableSession, EXPECT_EQ(kIncomplete,
jitter_buffer_->InsertPacket(*packet_, &retransmitted)); jitter_buffer_->InsertPacket(*packet_, &retransmitted));
frame_out = DecodeIncompleteFrame();
EXPECT_TRUE(frame_out == NULL);
packet_->seqNum += 2; packet_->seqNum += 2;
packet_->timestamp += 33 * 90; packet_->timestamp += 33 * 90;
packet_->is_first_packet_in_frame = true; packet_->is_first_packet_in_frame = true;
EXPECT_EQ(kDecodableSession, EXPECT_EQ(kIncomplete,
jitter_buffer_->InsertPacket(*packet_, &retransmitted)); jitter_buffer_->InsertPacket(*packet_, &retransmitted));
frame_out = DecodeIncompleteFrame();
CheckOutFrame(frame_out, packet_->sizeBytes, false);
jitter_buffer_->ReleaseFrame(frame_out);
} }
TEST_F(TestRunningJitterBuffer, Full) { TEST_F(TestRunningJitterBuffer, Full) {
@ -2433,7 +1840,6 @@ TEST_F(TestJitterBufferNack, NackTooOldPackets) {
EXPECT_GE(InsertFrame(kVideoFrameDelta), kNoError); EXPECT_GE(InsertFrame(kVideoFrameDelta), kNoError);
// Waiting for a key frame. // Waiting for a key frame.
EXPECT_FALSE(DecodeCompleteFrame()); EXPECT_FALSE(DecodeCompleteFrame());
EXPECT_FALSE(DecodeIncompleteFrame());
// The next complete continuous frame isn't a key frame, but we're waiting // The next complete continuous frame isn't a key frame, but we're waiting
// for one. // for one.
@ -2489,7 +1895,6 @@ TEST_F(TestJitterBufferNack, NackListFull) {
// The next complete continuous frame isn't a key frame, but we're waiting // The next complete continuous frame isn't a key frame, but we're waiting
// for one. // for one.
EXPECT_FALSE(DecodeCompleteFrame()); EXPECT_FALSE(DecodeCompleteFrame());
EXPECT_FALSE(DecodeIncompleteFrame());
EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError); EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError);
// Skipping ahead to the key frame. // Skipping ahead to the key frame.
EXPECT_TRUE(DecodeCompleteFrame()); EXPECT_TRUE(DecodeCompleteFrame());
@ -2593,10 +1998,9 @@ TEST_F(TestJitterBufferNack, UseNackToRecoverFirstKeyFrameSecondInQueue) {
TEST_F(TestJitterBufferNack, NormalOperation) { TEST_F(TestJitterBufferNack, NormalOperation) {
EXPECT_EQ(kNack, jitter_buffer_->nack_mode()); EXPECT_EQ(kNack, jitter_buffer_->nack_mode());
jitter_buffer_->SetDecodeErrorMode(kWithErrors);
EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError); EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError);
EXPECT_TRUE(DecodeIncompleteFrame()); EXPECT_TRUE(DecodeCompleteFrame());
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// | 1 | 2 | .. | 8 | 9 | x | 11 | 12 | .. | 19 | x | 21 | .. | 100 | // | 1 | 2 | .. | 8 | 9 | x | 11 | 12 | .. | 19 | x | 21 | .. | 100 |
@ -2604,20 +2008,19 @@ TEST_F(TestJitterBufferNack, NormalOperation) {
stream_generator_->GenerateFrame(kVideoFrameKey, 100, 0, stream_generator_->GenerateFrame(kVideoFrameKey, 100, 0,
clock_->TimeInMilliseconds()); clock_->TimeInMilliseconds());
clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs); clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
EXPECT_EQ(kDecodableSession, InsertPacketAndPop(0)); EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
// Verify that the frame is incomplete. // Verify that the frame is incomplete.
EXPECT_FALSE(DecodeCompleteFrame()); EXPECT_FALSE(DecodeCompleteFrame());
while (stream_generator_->PacketsRemaining() > 1) { while (stream_generator_->PacketsRemaining() > 1) {
if (stream_generator_->NextSequenceNumber() % 10 != 0) { if (stream_generator_->NextSequenceNumber() % 10 != 0) {
EXPECT_EQ(kDecodableSession, InsertPacketAndPop(0)); EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
} else { } else {
stream_generator_->NextPacket(NULL); // Drop packet stream_generator_->NextPacket(NULL); // Drop packet
} }
} }
EXPECT_EQ(kDecodableSession, InsertPacketAndPop(0)); EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
EXPECT_EQ(0, stream_generator_->PacketsRemaining()); EXPECT_EQ(0, stream_generator_->PacketsRemaining());
EXPECT_FALSE(DecodeCompleteFrame()); EXPECT_FALSE(DecodeCompleteFrame());
EXPECT_FALSE(DecodeIncompleteFrame());
bool request_key_frame = false; bool request_key_frame = false;
// Verify the NACK list. // Verify the NACK list.

View File

@ -140,8 +140,7 @@ VCMEncodedFrame* VCMReceiver::FrameForDecoding(uint16_t max_wait_time_ms,
min_playout_delay_ms = found_frame->EncodedImage().playout_delay_.min_ms; min_playout_delay_ms = found_frame->EncodedImage().playout_delay_.min_ms;
max_playout_delay_ms = found_frame->EncodedImage().playout_delay_.max_ms; max_playout_delay_ms = found_frame->EncodedImage().playout_delay_.max_ms;
} else { } else {
if (!jitter_buffer_.NextMaybeIncompleteTimestamp(&frame_timestamp)) return nullptr;
return nullptr;
} }
if (min_playout_delay_ms >= 0) if (min_playout_delay_ms >= 0)
@ -260,14 +259,6 @@ std::vector<uint16_t> VCMReceiver::NackList(bool* request_key_frame) {
return jitter_buffer_.GetNackList(request_key_frame); return jitter_buffer_.GetNackList(request_key_frame);
} }
void VCMReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) {
jitter_buffer_.SetDecodeErrorMode(decode_error_mode);
}
VCMDecodeErrorMode VCMReceiver::DecodeErrorMode() const {
return jitter_buffer_.decode_error_mode();
}
void VCMReceiver::RegisterStatsCallback( void VCMReceiver::RegisterStatsCallback(
VCMReceiveStatisticsCallback* callback) { VCMReceiveStatisticsCallback* callback) {
jitter_buffer_.RegisterStatsCallback(callback); jitter_buffer_.RegisterStatsCallback(callback);

View File

@ -79,10 +79,6 @@ class VCMReceiver {
VCMNackMode NackMode() const; VCMNackMode NackMode() const;
std::vector<uint16_t> NackList(bool* request_key_frame); std::vector<uint16_t> NackList(bool* request_key_frame);
// Decoding with errors.
void SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode);
VCMDecodeErrorMode DecodeErrorMode() const;
void RegisterStatsCallback(VCMReceiveStatisticsCallback* callback); void RegisterStatsCallback(VCMReceiveStatisticsCallback* callback);
void TriggerDecoderShutdown(); void TriggerDecoderShutdown();

View File

@ -36,7 +36,6 @@ uint16_t BufferToUWord16(const uint8_t* dataBuffer) {
VCMSessionInfo::VCMSessionInfo() VCMSessionInfo::VCMSessionInfo()
: complete_(false), : complete_(false),
decodable_(false),
frame_type_(kVideoFrameDelta), frame_type_(kVideoFrameDelta),
packets_(), packets_(),
empty_seq_num_low_(-1), empty_seq_num_low_(-1),
@ -167,7 +166,6 @@ void VCMSessionInfo::SetGofInfo(const GofInfoVP9& gof_info, size_t idx) {
void VCMSessionInfo::Reset() { void VCMSessionInfo::Reset() {
complete_ = false; complete_ = false;
decodable_ = false;
frame_type_ = kVideoFrameDelta; frame_type_ = kVideoFrameDelta;
packets_.clear(); packets_.clear();
empty_seq_num_low_ = -1; empty_seq_num_low_ = -1;
@ -291,37 +289,10 @@ void VCMSessionInfo::UpdateCompleteSession() {
} }
} }
void VCMSessionInfo::UpdateDecodableSession(const FrameData& frame_data) {
// Irrelevant if session is already complete or decodable
if (complete_ || decodable_)
return;
// TODO(agalusza): Account for bursty loss.
// TODO(agalusza): Refine these values to better approximate optimal ones.
// Do not decode frames if the RTT is lower than this.
const int64_t kRttThreshold = 100;
// Do not decode frames if the number of packets is between these two
// thresholds.
const float kLowPacketPercentageThreshold = 0.2f;
const float kHighPacketPercentageThreshold = 0.8f;
if (frame_data.rtt_ms < kRttThreshold || frame_type_ == kVideoFrameKey ||
!HaveFirstPacket() ||
(NumPackets() <= kHighPacketPercentageThreshold *
frame_data.rolling_average_packets_per_frame &&
NumPackets() > kLowPacketPercentageThreshold *
frame_data.rolling_average_packets_per_frame))
return;
decodable_ = true;
}
bool VCMSessionInfo::complete() const { bool VCMSessionInfo::complete() const {
return complete_; return complete_;
} }
bool VCMSessionInfo::decodable() const {
return decodable_;
}
// Find the end of the NAL unit which the packet pointed to by |packet_it| // Find the end of the NAL unit which the packet pointed to by |packet_it|
// belongs to. Returns an iterator to the last packet of the frame if the end // belongs to. Returns an iterator to the last packet of the frame if the end
// of the NAL unit wasn't found. // of the NAL unit wasn't found.
@ -448,7 +419,6 @@ bool VCMSessionInfo::HaveLastPacket() const {
int VCMSessionInfo::InsertPacket(const VCMPacket& packet, int VCMSessionInfo::InsertPacket(const VCMPacket& packet,
uint8_t* frame_buffer, uint8_t* frame_buffer,
VCMDecodeErrorMode decode_error_mode,
const FrameData& frame_data) { const FrameData& frame_data) {
if (packet.frameType == kEmptyFrame) { if (packet.frameType == kEmptyFrame) {
// Update sequence number of an empty packet. // Update sequence number of an empty packet.
@ -526,10 +496,7 @@ int VCMSessionInfo::InsertPacket(const VCMPacket& packet,
size_t returnLength = InsertBuffer(frame_buffer, packet_list_it); size_t returnLength = InsertBuffer(frame_buffer, packet_list_it);
UpdateCompleteSession(); UpdateCompleteSession();
if (decode_error_mode == kWithErrors)
decodable_ = true;
else if (decode_error_mode == kSelectiveErrors)
UpdateDecodableSession(frame_data);
return static_cast<int>(returnLength); return static_cast<int>(returnLength);
} }

View File

@ -40,10 +40,8 @@ class VCMSessionInfo {
void Reset(); void Reset();
int InsertPacket(const VCMPacket& packet, int InsertPacket(const VCMPacket& packet,
uint8_t* frame_buffer, uint8_t* frame_buffer,
VCMDecodeErrorMode enable_decodable_state,
const FrameData& frame_data); const FrameData& frame_data);
bool complete() const; bool complete() const;
bool decodable() const;
// Makes the frame decodable. I.e., only contain decodable NALUs. All // Makes the frame decodable. I.e., only contain decodable NALUs. All
// non-decodable NALUs will be deleted and packets will be moved to in // non-decodable NALUs will be deleted and packets will be moved to in
@ -104,26 +102,7 @@ class VCMSessionInfo {
size_t DeletePacketData(PacketIterator start, PacketIterator end); size_t DeletePacketData(PacketIterator start, PacketIterator end);
void UpdateCompleteSession(); void UpdateCompleteSession();
// When enabled, determine if session is decodable, i.e. incomplete but
// would be sent to the decoder.
// Note: definition assumes random loss.
// A frame is defined to be decodable when:
// Round trip time is higher than threshold
// It is not a key frame
// It has the first packet: In VP8 the first packet contains all or part of
// the first partition, which consists of the most relevant information for
// decoding.
// Either more than the upper threshold of the average number of packets per
// frame is present
// or less than the lower threshold of the average number of packets per
// frame is present: suggests a small frame. Such a frame is unlikely
// to contain many motion vectors, so having the first packet will
// likely suffice. Once we have more than the lower threshold of the
// frame, we know that the frame is medium or large-sized.
void UpdateDecodableSession(const FrameData& frame_data);
bool complete_; bool complete_;
bool decodable_;
webrtc::FrameType frame_type_; webrtc::FrameType frame_type_;
// Packets in this frame. // Packets in this frame.
PacketList packets_; PacketList packets_;

View File

@ -118,18 +118,16 @@ TEST_F(TestSessionInfo, TestSimpleAPIs) {
packet_.sizeBytes = packet_buffer_size(); packet_.sizeBytes = packet_buffer_size();
packet_.frameType = kVideoFrameKey; packet_.frameType = kVideoFrameKey;
FillPacket(0); FillPacket(0);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
EXPECT_FALSE(session_.HaveLastPacket()); EXPECT_FALSE(session_.HaveLastPacket());
EXPECT_EQ(kVideoFrameKey, session_.FrameType()); EXPECT_EQ(kVideoFrameKey, session_.FrameType());
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = true; packet_.markerBit = true;
packet_.seqNum += 1; packet_.seqNum += 1;
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
EXPECT_TRUE(session_.HaveLastPacket()); EXPECT_TRUE(session_.HaveLastPacket());
EXPECT_EQ(packet_.seqNum, session_.HighSequenceNumber()); EXPECT_EQ(packet_.seqNum, session_.HighSequenceNumber());
EXPECT_EQ(0xFFFE, session_.LowSequenceNumber()); EXPECT_EQ(0xFFFE, session_.LowSequenceNumber());
@ -141,8 +139,7 @@ TEST_F(TestSessionInfo, TestSimpleAPIs) {
packet_.seqNum = 2; packet_.seqNum = 2;
packet_.sizeBytes = 0; packet_.sizeBytes = 0;
packet_.frameType = kEmptyFrame; packet_.frameType = kEmptyFrame;
EXPECT_EQ( EXPECT_EQ(0, session_.InsertPacket(packet_, frame_buffer_, frame_data));
0, session_.InsertPacket(packet_, frame_buffer_, kNoErrors, frame_data));
EXPECT_EQ(packet_.seqNum, session_.HighSequenceNumber()); EXPECT_EQ(packet_.seqNum, session_.HighSequenceNumber());
} }
@ -151,25 +148,22 @@ TEST_F(TestSessionInfo, NormalOperation) {
packet_.is_first_packet_in_frame = true; packet_.is_first_packet_in_frame = true;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(0); FillPacket(0);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
for (int i = 1; i < 9; ++i) { for (int i = 1; i < 9; ++i) {
packet_.seqNum += 1; packet_.seqNum += 1;
FillPacket(i); FillPacket(i);
ASSERT_EQ(packet_buffer_size(), ASSERT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket( packet_, frame_buffer_, frame_data)));
packet_, frame_buffer_, kNoErrors, frame_data)));
} }
packet_.seqNum += 1; packet_.seqNum += 1;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(9); FillPacket(9);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
EXPECT_EQ(10 * packet_buffer_size(), session_.SessionLength()); EXPECT_EQ(10 * packet_buffer_size(), session_.SessionLength());
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
@ -178,77 +172,24 @@ TEST_F(TestSessionInfo, NormalOperation) {
} }
} }
TEST_F(TestSessionInfo, ErrorsEqualDecodableState) {
packet_.seqNum = 0xFFFF;
packet_.is_first_packet_in_frame = false;
packet_.markerBit = false;
FillPacket(3);
EXPECT_EQ(packet_buffer_size(),
static_cast<size_t>(session_.InsertPacket(
packet_, frame_buffer_, kWithErrors, frame_data)));
EXPECT_TRUE(session_.decodable());
}
TEST_F(TestSessionInfo, SelectiveDecodableState) {
packet_.seqNum = 0xFFFF;
packet_.is_first_packet_in_frame = false;
packet_.markerBit = false;
FillPacket(1);
frame_data.rolling_average_packets_per_frame = 11;
frame_data.rtt_ms = 150;
EXPECT_EQ(packet_buffer_size(),
static_cast<size_t>(session_.InsertPacket(
packet_, frame_buffer_, kSelectiveErrors, frame_data)));
EXPECT_FALSE(session_.decodable());
packet_.seqNum -= 1;
FillPacket(0);
packet_.is_first_packet_in_frame = true;
EXPECT_EQ(packet_buffer_size(),
static_cast<size_t>(session_.InsertPacket(
packet_, frame_buffer_, kSelectiveErrors, frame_data)));
EXPECT_TRUE(session_.decodable());
packet_.is_first_packet_in_frame = false;
packet_.seqNum += 1;
for (int i = 2; i < 8; ++i) {
packet_.seqNum += 1;
FillPacket(i);
EXPECT_EQ(packet_buffer_size(),
static_cast<size_t>(session_.InsertPacket(
packet_, frame_buffer_, kSelectiveErrors, frame_data)));
EXPECT_TRUE(session_.decodable());
}
packet_.seqNum += 1;
FillPacket(8);
EXPECT_EQ(packet_buffer_size(),
static_cast<size_t>(session_.InsertPacket(
packet_, frame_buffer_, kSelectiveErrors, frame_data)));
EXPECT_TRUE(session_.decodable());
}
TEST_F(TestSessionInfo, OutOfBoundsPackets1PacketFrame) { TEST_F(TestSessionInfo, OutOfBoundsPackets1PacketFrame) {
packet_.seqNum = 0x0001; packet_.seqNum = 0x0001;
packet_.is_first_packet_in_frame = true; packet_.is_first_packet_in_frame = true;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.seqNum = 0x0004; packet_.seqNum = 0x0004;
packet_.is_first_packet_in_frame = true; packet_.is_first_packet_in_frame = true;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(1); FillPacket(1);
EXPECT_EQ( EXPECT_EQ(-3, session_.InsertPacket(packet_, frame_buffer_, frame_data));
-3, session_.InsertPacket(packet_, frame_buffer_, kNoErrors, frame_data));
packet_.seqNum = 0x0000; packet_.seqNum = 0x0000;
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ( EXPECT_EQ(-3, session_.InsertPacket(packet_, frame_buffer_, frame_data));
-3, session_.InsertPacket(packet_, frame_buffer_, kNoErrors, frame_data));
} }
TEST_F(TestSessionInfo, SetMarkerBitOnce) { TEST_F(TestSessionInfo, SetMarkerBitOnce) {
@ -256,15 +197,13 @@ TEST_F(TestSessionInfo, SetMarkerBitOnce) {
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
++packet_.seqNum; ++packet_.seqNum;
packet_.is_first_packet_in_frame = true; packet_.is_first_packet_in_frame = true;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(1); FillPacket(1);
EXPECT_EQ( EXPECT_EQ(-3, session_.InsertPacket(packet_, frame_buffer_, frame_data));
-3, session_.InsertPacket(packet_, frame_buffer_, kNoErrors, frame_data));
} }
TEST_F(TestSessionInfo, OutOfBoundsPacketsBase) { TEST_F(TestSessionInfo, OutOfBoundsPacketsBase) {
@ -273,29 +212,25 @@ TEST_F(TestSessionInfo, OutOfBoundsPacketsBase) {
packet_.is_first_packet_in_frame = true; packet_.is_first_packet_in_frame = true;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
// Insert an older packet with a first packet set. // Insert an older packet with a first packet set.
packet_.seqNum = 0x0004; packet_.seqNum = 0x0004;
packet_.is_first_packet_in_frame = true; packet_.is_first_packet_in_frame = true;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(1); FillPacket(1);
EXPECT_EQ( EXPECT_EQ(-3, session_.InsertPacket(packet_, frame_buffer_, frame_data));
-3, session_.InsertPacket(packet_, frame_buffer_, kNoErrors, frame_data));
packet_.seqNum = 0x0006; packet_.seqNum = 0x0006;
packet_.is_first_packet_in_frame = true; packet_.is_first_packet_in_frame = true;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.seqNum = 0x0008; packet_.seqNum = 0x0008;
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(1); FillPacket(1);
EXPECT_EQ( EXPECT_EQ(-3, session_.InsertPacket(packet_, frame_buffer_, frame_data));
-3, session_.InsertPacket(packet_, frame_buffer_, kNoErrors, frame_data));
} }
TEST_F(TestSessionInfo, OutOfBoundsPacketsWrap) { TEST_F(TestSessionInfo, OutOfBoundsPacketsWrap) {
@ -303,36 +238,31 @@ TEST_F(TestSessionInfo, OutOfBoundsPacketsWrap) {
packet_.is_first_packet_in_frame = true; packet_.is_first_packet_in_frame = true;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.seqNum = 0x0004; packet_.seqNum = 0x0004;
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.seqNum = 0x0002; packet_.seqNum = 0x0002;
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
ASSERT_EQ(packet_buffer_size(), ASSERT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.seqNum = 0xFFF0; packet_.seqNum = 0xFFF0;
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ( EXPECT_EQ(-3, session_.InsertPacket(packet_, frame_buffer_, frame_data));
-3, session_.InsertPacket(packet_, frame_buffer_, kNoErrors, frame_data));
packet_.seqNum = 0x0006; packet_.seqNum = 0x0006;
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ( EXPECT_EQ(-3, session_.InsertPacket(packet_, frame_buffer_, frame_data));
-3, session_.InsertPacket(packet_, frame_buffer_, kNoErrors, frame_data));
} }
TEST_F(TestSessionInfo, OutOfBoundsOutOfOrder) { TEST_F(TestSessionInfo, OutOfBoundsOutOfOrder) {
@ -342,44 +272,38 @@ TEST_F(TestSessionInfo, OutOfBoundsOutOfOrder) {
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
// Insert an older packet with a first packet set. // Insert an older packet with a first packet set.
packet_.seqNum = 0x0005; packet_.seqNum = 0x0005;
packet_.is_first_packet_in_frame = true; packet_.is_first_packet_in_frame = true;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.seqNum = 0x0004; packet_.seqNum = 0x0004;
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ( EXPECT_EQ(-3, session_.InsertPacket(packet_, frame_buffer_, frame_data));
-3, session_.InsertPacket(packet_, frame_buffer_, kNoErrors, frame_data));
packet_.seqNum = 0x0010; packet_.seqNum = 0x0010;
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.seqNum = 0x0008; packet_.seqNum = 0x0008;
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.seqNum = 0x0009; packet_.seqNum = 0x0009;
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ( EXPECT_EQ(-3, session_.InsertPacket(packet_, frame_buffer_, frame_data));
-3, session_.InsertPacket(packet_, frame_buffer_, kNoErrors, frame_data));
} }
TEST_F(TestNalUnits, OnlyReceivedEmptyPacket) { TEST_F(TestNalUnits, OnlyReceivedEmptyPacket) {
@ -389,8 +313,7 @@ TEST_F(TestNalUnits, OnlyReceivedEmptyPacket) {
packet_.sizeBytes = 0; packet_.sizeBytes = 0;
packet_.seqNum = 0; packet_.seqNum = 0;
packet_.markerBit = false; packet_.markerBit = false;
EXPECT_EQ( EXPECT_EQ(0, session_.InsertPacket(packet_, frame_buffer_, frame_data));
0, session_.InsertPacket(packet_, frame_buffer_, kNoErrors, frame_data));
EXPECT_EQ(0U, session_.MakeDecodable()); EXPECT_EQ(0U, session_.MakeDecodable());
EXPECT_EQ(0U, session_.SessionLength()); EXPECT_EQ(0U, session_.SessionLength());
@ -402,18 +325,16 @@ TEST_F(TestNalUnits, OneIsolatedNaluLoss) {
packet_.seqNum = 0; packet_.seqNum = 0;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(0); FillPacket(0);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.completeNALU = kNaluComplete; packet_.completeNALU = kNaluComplete;
packet_.seqNum += 2; packet_.seqNum += 2;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(2); FillPacket(2);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
EXPECT_EQ(0U, session_.MakeDecodable()); EXPECT_EQ(0U, session_.MakeDecodable());
EXPECT_EQ(2 * packet_buffer_size(), session_.SessionLength()); EXPECT_EQ(2 * packet_buffer_size(), session_.SessionLength());
@ -429,18 +350,16 @@ TEST_F(TestNalUnits, LossInMiddleOfNalu) {
packet_.seqNum = 0; packet_.seqNum = 0;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(0); FillPacket(0);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.completeNALU = kNaluEnd; packet_.completeNALU = kNaluEnd;
packet_.seqNum += 2; packet_.seqNum += 2;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(2); FillPacket(2);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
EXPECT_EQ(packet_buffer_size(), session_.MakeDecodable()); EXPECT_EQ(packet_buffer_size(), session_.MakeDecodable());
EXPECT_EQ(packet_buffer_size(), session_.SessionLength()); EXPECT_EQ(packet_buffer_size(), session_.SessionLength());
@ -454,18 +373,16 @@ TEST_F(TestNalUnits, StartAndEndOfLastNalUnitLost) {
packet_.seqNum = 0; packet_.seqNum = 0;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(0); FillPacket(0);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.completeNALU = kNaluIncomplete; packet_.completeNALU = kNaluIncomplete;
packet_.seqNum += 2; packet_.seqNum += 2;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
EXPECT_EQ(packet_buffer_size(), session_.MakeDecodable()); EXPECT_EQ(packet_buffer_size(), session_.MakeDecodable());
EXPECT_EQ(packet_buffer_size(), session_.SessionLength()); EXPECT_EQ(packet_buffer_size(), session_.SessionLength());
@ -480,27 +397,24 @@ TEST_F(TestNalUnits, ReorderWrapNoLoss) {
packet_.seqNum += 1; packet_.seqNum += 1;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.is_first_packet_in_frame = true; packet_.is_first_packet_in_frame = true;
packet_.completeNALU = kNaluComplete; packet_.completeNALU = kNaluComplete;
packet_.seqNum -= 1; packet_.seqNum -= 1;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(0); FillPacket(0);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.completeNALU = kNaluEnd; packet_.completeNALU = kNaluEnd;
packet_.seqNum += 2; packet_.seqNum += 2;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(2); FillPacket(2);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
EXPECT_EQ(0U, session_.MakeDecodable()); EXPECT_EQ(0U, session_.MakeDecodable());
EXPECT_EQ(3 * packet_buffer_size(), session_.SessionLength()); EXPECT_EQ(3 * packet_buffer_size(), session_.SessionLength());
@ -514,18 +428,16 @@ TEST_F(TestNalUnits, WrapLosses) {
packet_.completeNALU = kNaluIncomplete; packet_.completeNALU = kNaluIncomplete;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.completeNALU = kNaluEnd; packet_.completeNALU = kNaluEnd;
packet_.seqNum += 2; packet_.seqNum += 2;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(2); FillPacket(2);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
EXPECT_EQ(2 * packet_buffer_size(), session_.MakeDecodable()); EXPECT_EQ(2 * packet_buffer_size(), session_.MakeDecodable());
EXPECT_EQ(0U, session_.SessionLength()); EXPECT_EQ(0U, session_.SessionLength());
@ -539,18 +451,16 @@ TEST_F(TestNalUnits, ReorderWrapLosses) {
packet_.seqNum += 2; packet_.seqNum += 2;
packet_.markerBit = true; packet_.markerBit = true;
FillPacket(2); FillPacket(2);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
packet_.seqNum -= 2; packet_.seqNum -= 2;
packet_.is_first_packet_in_frame = false; packet_.is_first_packet_in_frame = false;
packet_.completeNALU = kNaluIncomplete; packet_.completeNALU = kNaluIncomplete;
packet_.markerBit = false; packet_.markerBit = false;
FillPacket(1); FillPacket(1);
EXPECT_EQ(packet_buffer_size(), EXPECT_EQ(packet_buffer_size(), static_cast<size_t>(session_.InsertPacket(
static_cast<size_t>(session_.InsertPacket(packet_, frame_buffer_, packet_, frame_buffer_, frame_data)));
kNoErrors, frame_data)));
EXPECT_EQ(2 * packet_buffer_size(), session_.MakeDecodable()); EXPECT_EQ(2 * packet_buffer_size(), session_.MakeDecodable());
EXPECT_EQ(0U, session_.SessionLength()); EXPECT_EQ(0U, session_.SessionLength());

View File

@ -99,9 +99,8 @@ class VideoCodingModuleImpl : public VideoCodingModule {
return receiver_.IncomingPacket(incomingPayload, payloadLength, rtpInfo); return receiver_.IncomingPacket(incomingPayload, payloadLength, rtpInfo);
} }
int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode, int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode) override {
VCMDecodeErrorMode errorMode) override { return receiver_.SetReceiverRobustnessMode(robustnessMode);
return receiver_.SetReceiverRobustnessMode(robustnessMode, errorMode);
} }
void SetNackSettings(size_t max_nack_list_size, void SetNackSettings(size_t max_nack_list_size,

View File

@ -131,15 +131,12 @@ class VideoReceiver : public Module {
// DEPRECATED. // DEPRECATED.
int SetReceiverRobustnessMode( int SetReceiverRobustnessMode(
VideoCodingModule::ReceiverRobustness robustnessMode, VideoCodingModule::ReceiverRobustness robustnessMode);
VCMDecodeErrorMode errorMode);
void SetNackSettings(size_t max_nack_list_size, void SetNackSettings(size_t max_nack_list_size,
int max_packet_age_to_nack, int max_packet_age_to_nack,
int max_incomplete_time_ms); int max_incomplete_time_ms);
void SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode);
int32_t SetReceiveChannelParameters(int64_t rtt); int32_t SetReceiveChannelParameters(int64_t rtt);
int32_t SetVideoProtection(VCMVideoProtection videoProtection, bool enable); int32_t SetVideoProtection(VCMVideoProtection videoProtection, bool enable);

View File

@ -158,8 +158,6 @@ int32_t VideoReceiver::SetReceiveChannelParameters(int64_t rtt) {
// between the protection method and decoding with or without errors. // between the protection method and decoding with or without errors.
int32_t VideoReceiver::SetVideoProtection(VCMVideoProtection videoProtection, int32_t VideoReceiver::SetVideoProtection(VCMVideoProtection videoProtection,
bool enable) { bool enable) {
// By default, do not decode with errors.
_receiver.SetDecodeErrorMode(kNoErrors);
switch (videoProtection) { switch (videoProtection) {
case kProtectionNack: { case kProtectionNack: {
RTC_DCHECK(enable); RTC_DCHECK(enable);
@ -171,7 +169,6 @@ int32_t VideoReceiver::SetVideoProtection(VCMVideoProtection videoProtection,
RTC_DCHECK(enable); RTC_DCHECK(enable);
_receiver.SetNackMode(kNack, media_optimization::kLowRttNackMs, _receiver.SetNackMode(kNack, media_optimization::kLowRttNackMs,
media_optimization::kMaxRttDelayThreshold); media_optimization::kMaxRttDelayThreshold);
_receiver.SetDecodeErrorMode(kNoErrors);
break; break;
} }
case kProtectionFEC: case kProtectionFEC:
@ -179,7 +176,6 @@ int32_t VideoReceiver::SetVideoProtection(VCMVideoProtection videoProtection,
// No receiver-side protection. // No receiver-side protection.
RTC_DCHECK(enable); RTC_DCHECK(enable);
_receiver.SetNackMode(kNoNack, -1, -1); _receiver.SetNackMode(kNoNack, -1, -1);
_receiver.SetDecodeErrorMode(kWithErrors);
break; break;
} }
return VCM_OK; return VCM_OK;
@ -439,10 +435,8 @@ int32_t VideoReceiver::Delay() const {
return _timing->TargetVideoDelay(); return _timing->TargetVideoDelay();
} }
// Only used by VCMRobustnessTest.
int VideoReceiver::SetReceiverRobustnessMode( int VideoReceiver::SetReceiverRobustnessMode(
VideoCodingModule::ReceiverRobustness robustnessMode, VideoCodingModule::ReceiverRobustness robustnessMode) {
VCMDecodeErrorMode decode_error_mode) {
RTC_DCHECK_RUN_ON(&construction_thread_checker_); RTC_DCHECK_RUN_ON(&construction_thread_checker_);
RTC_DCHECK(!IsDecoderThreadRunning()); RTC_DCHECK(!IsDecoderThreadRunning());
switch (robustnessMode) { switch (robustnessMode) {
@ -457,16 +451,9 @@ int VideoReceiver::SetReceiverRobustnessMode(
RTC_NOTREACHED(); RTC_NOTREACHED();
return VCM_PARAMETER_ERROR; return VCM_PARAMETER_ERROR;
} }
_receiver.SetDecodeErrorMode(decode_error_mode);
return VCM_OK; return VCM_OK;
} }
void VideoReceiver::SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) {
RTC_DCHECK_RUN_ON(&construction_thread_checker_);
RTC_DCHECK(!IsDecoderThreadRunning());
_receiver.SetDecodeErrorMode(decode_error_mode);
}
void VideoReceiver::SetNackSettings(size_t max_nack_list_size, void VideoReceiver::SetNackSettings(size_t max_nack_list_size,
int max_packet_age_to_nack, int max_packet_age_to_nack,
int max_incomplete_time_ms) { int max_incomplete_time_ms) {

View File

@ -41,9 +41,7 @@ VideoStreamDecoder::VideoStreamDecoder(
enable_nack ? (enable_fec ? kProtectionNackFEC : kProtectionNack) enable_nack ? (enable_fec ? kProtectionNackFEC : kProtectionNack)
: kProtectionNone; : kProtectionNone;
VCMDecodeErrorMode decode_error_mode = enable_nack ? kNoErrors : kWithErrors;
video_receiver_->SetVideoProtection(video_protection, true); video_receiver_->SetVideoProtection(video_protection, true);
video_receiver_->SetDecodeErrorMode(decode_error_mode);
VCMPacketRequestCallback* packet_request_callback = VCMPacketRequestCallback* packet_request_callback =
enable_nack ? vcm_packet_request_callback : nullptr; enable_nack ? vcm_packet_request_callback : nullptr;
video_receiver_->RegisterPacketRequestCallback(packet_request_callback); video_receiver_->RegisterPacketRequestCallback(packet_request_callback);