Removed lines preventing simultaneous kHardNack and decoding with errors. Also made changes recommended by gcl lint (with the exception of changing non-const references to pointers).

Propagated orthogonal API for decoding with errors from VideoCodingModule to VCMJitterBuffer.
Modified VCMJitterBuffer to allow three error modes: kNoErrors, kSelectiveErrors, kWithErrors.

R=marpan@google.com, mikhal@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/1846004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4463 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
agalusza@google.com 2013-08-01 03:15:08 +00:00
parent d64719d895
commit a7e360e89b
15 changed files with 484 additions and 467 deletions

View File

@ -41,6 +41,19 @@ class EventFactoryImpl : public EventFactory {
}
};
// 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
{
public:
@ -566,7 +579,7 @@ public:
// Return value : VCM_OK, on success;
// < 0, on error.
virtual int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,
DecodeErrors errorMode) = 0;
VCMDecodeErrorMode errorMode) = 0;
// 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

View File

@ -19,7 +19,6 @@
namespace webrtc {
TEST(TestDecodingState, Sanity) {
VCMDecodingState dec_state;
dec_state.Reset();
@ -42,38 +41,38 @@ TEST(TestDecodingState, FrameContinuity) {
FrameData frame_data;
frame_data.rtt_ms = 0;
frame_data.rolling_average_packets_per_frame = -1;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
// Always start with a key frame.
dec_state.Reset();
EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
packet->frameType = kVideoFrameKey;
frame_key.InsertPacket(*packet, 0, false, frame_data);
frame_key.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame_key));
dec_state.SetState(&frame);
frame.Reset();
packet->frameType = kVideoFrameDelta;
// Use pictureId
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 0x0002;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
frame.Reset();
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 0;
packet->seqNum = 10;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
// Use sequence numbers.
packet->codecSpecificHeader.codecHeader.VP8.pictureId = kNoPictureId;
frame.Reset();
packet->seqNum = dec_state.sequence_num() - 1u;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
frame.Reset();
packet->seqNum = dec_state.sequence_num() + 1u;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
// Insert another packet to this frame
packet->seqNum++;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
// Verify wrap.
EXPECT_EQ(dec_state.sequence_num(), 0xffff);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
@ -88,7 +87,7 @@ TEST(TestDecodingState, FrameContinuity) {
packet->seqNum = 1;
packet->timestamp = 1;
EXPECT_TRUE(dec_state.full_sync());
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync());
frame.Reset();
@ -98,7 +97,7 @@ TEST(TestDecodingState, FrameContinuity) {
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 1;
packet->seqNum = 2;
packet->timestamp = 2;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync());
@ -109,7 +108,7 @@ TEST(TestDecodingState, FrameContinuity) {
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 3;
packet->seqNum = 4;
packet->timestamp = 4;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
// Now insert the next non-base layer (belonging to a next tl0PicId).
frame.Reset();
@ -118,7 +117,7 @@ TEST(TestDecodingState, FrameContinuity) {
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 4;
packet->seqNum = 5;
packet->timestamp = 5;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
// Checking continuity and not updating the state - this should not trigger
// an update of sync state.
EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
@ -130,7 +129,7 @@ TEST(TestDecodingState, FrameContinuity) {
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 5;
packet->seqNum = 6;
packet->timestamp = 6;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame);
EXPECT_FALSE(dec_state.full_sync());
@ -142,7 +141,7 @@ TEST(TestDecodingState, FrameContinuity) {
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 6;
packet->seqNum = 7;
packet->timestamp = 7;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
dec_state.SetState(&frame);
EXPECT_FALSE(dec_state.full_sync());
frame.Reset();
@ -151,7 +150,7 @@ TEST(TestDecodingState, FrameContinuity) {
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 7;
packet->seqNum = 8;
packet->timestamp = 8;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
// The current frame is not continuous
dec_state.SetState(&frame);
@ -171,7 +170,7 @@ TEST(TestDecodingState, UpdateOldPacket) {
FrameData frame_data;
frame_data.rtt_ms = 0;
frame_data.rolling_average_packets_per_frame = -1;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
dec_state.SetState(&frame);
EXPECT_EQ(dec_state.sequence_num(), 1);
// Insert an empty packet that does not belong to the same frame.
@ -223,7 +222,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
FrameData frame_data;
frame_data.rtt_ms = 0;
frame_data.rolling_average_packets_per_frame = -1;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
dec_state.SetState(&frame);
// tl0PicIdx 0, temporal id 1.
frame.Reset();
@ -232,7 +231,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
packet->codecSpecificHeader.codecHeader.VP8.tl0PicIdx = 0;
packet->codecSpecificHeader.codecHeader.VP8.temporalIdx = 1;
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 1;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync());
@ -244,7 +243,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
packet->codecSpecificHeader.codecHeader.VP8.tl0PicIdx = 0;
packet->codecSpecificHeader.codecHeader.VP8.temporalIdx = 3;
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 3;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame);
EXPECT_FALSE(dec_state.full_sync());
@ -255,7 +254,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
packet->codecSpecificHeader.codecHeader.VP8.tl0PicIdx = 1;
packet->codecSpecificHeader.codecHeader.VP8.temporalIdx = 0;
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 4;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame);
EXPECT_FALSE(dec_state.full_sync());
@ -269,7 +268,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
packet->codecSpecificHeader.codecHeader.VP8.tl0PicIdx = 2;
packet->codecSpecificHeader.codecHeader.VP8.temporalIdx = 0;
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 5;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync());
@ -282,7 +281,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
packet->codecSpecificHeader.codecHeader.VP8.tl0PicIdx = 3;
packet->codecSpecificHeader.codecHeader.VP8.temporalIdx = 0;
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 6;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
EXPECT_TRUE(dec_state.full_sync());
frame.Reset();
@ -293,7 +292,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
packet->codecSpecificHeader.codecHeader.VP8.tl0PicIdx = 4;
packet->codecSpecificHeader.codecHeader.VP8.temporalIdx = 0;
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 8;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
EXPECT_TRUE(dec_state.full_sync());
dec_state.SetState(&frame);
@ -309,7 +308,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
packet->codecSpecificHeader.codecHeader.VP8.temporalIdx = 2;
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 9;
packet->codecSpecificHeader.codecHeader.VP8.layerSync = true;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync());
@ -330,7 +329,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
packet->codecSpecificHeader.codecHeader.VP8.temporalIdx = 0;
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 0;
packet->codecSpecificHeader.codecHeader.VP8.layerSync = false;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync());
// Layer 2 - 2 packets (insert one, lose one).
@ -344,7 +343,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
packet->codecSpecificHeader.codecHeader.VP8.temporalIdx = 2;
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 1;
packet->codecSpecificHeader.codecHeader.VP8.layerSync = true;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
// Layer 1
frame.Reset();
@ -357,7 +356,7 @@ TEST(TestDecodingState, MultiLayerBehavior) {
packet->codecSpecificHeader.codecHeader.VP8.temporalIdx = 1;
packet->codecSpecificHeader.codecHeader.VP8.pictureId = 2;
packet->codecSpecificHeader.codecHeader.VP8.layerSync = true;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
EXPECT_TRUE(dec_state.full_sync());
@ -379,7 +378,7 @@ TEST(TestDecodingState, DiscontinuousPicIdContinuousSeqNum) {
FrameData frame_data;
frame_data.rtt_ms = 0;
frame_data.rolling_average_packets_per_frame = -1;
frame.InsertPacket(packet, 0, false, frame_data);
frame.InsertPacket(packet, 0, kNoErrors, frame_data);
dec_state.SetState(&frame);
EXPECT_TRUE(dec_state.full_sync());
@ -391,7 +390,7 @@ TEST(TestDecodingState, DiscontinuousPicIdContinuousSeqNum) {
++packet.seqNum;
packet.codecSpecificHeader.codecHeader.VP8.temporalIdx = 1;
packet.codecSpecificHeader.codecHeader.VP8.pictureId = 2;
frame.InsertPacket(packet, 0, false, frame_data);
frame.InsertPacket(packet, 0, kNoErrors, frame_data);
EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
dec_state.SetState(&frame);
EXPECT_FALSE(dec_state.full_sync());
@ -408,13 +407,13 @@ TEST(TestDecodingState, OldInput) {
FrameData frame_data;
frame_data.rtt_ms = 0;
frame_data.rolling_average_packets_per_frame = -1;
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
dec_state.SetState(&frame);
packet->timestamp = 9;
EXPECT_TRUE(dec_state.IsOldPacket(packet));
// Check for old frame
frame.Reset();
frame.InsertPacket(*packet, 0, false, frame_data);
frame.InsertPacket(*packet, 0, kNoErrors, frame_data);
EXPECT_TRUE(dec_state.IsOldFrame(&frame));

View File

@ -82,8 +82,9 @@ VCMFrameBuffer::IsSessionComplete() const {
// Insert packet
VCMFrameBufferEnum
VCMFrameBuffer::InsertPacket(const VCMPacket& packet, int64_t timeInMs,
bool enableDecodableState,
VCMFrameBuffer::InsertPacket(const VCMPacket& packet,
int64_t timeInMs,
VCMDecodeErrorMode decode_error_mode,
const FrameData& frame_data) {
// is this packet part of this frame
if (TimeStamp() && (TimeStamp() != packet.timestamp)) {
@ -141,7 +142,7 @@ VCMFrameBuffer::InsertPacket(const VCMPacket& packet, int64_t timeInMs,
CopyCodecSpecific(&packet.codecSpecificHeader);
int retVal = _sessionInfo.InsertPacket(packet, _buffer,
enableDecodableState,
decode_error_mode,
frame_data);
if (retVal == -1) {
return kSizeError;

View File

@ -12,6 +12,7 @@
#define WEBRTC_MODULES_VIDEO_CODING_MAIN_SOURCE_FRAME_BUFFER_H_
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
#include "webrtc/modules/video_coding/main/source/jitter_buffer_common.h"
#include "webrtc/modules/video_coding/main/source/session_info.h"
@ -30,7 +31,7 @@ class VCMFrameBuffer : public VCMEncodedFrame {
VCMFrameBufferEnum InsertPacket(const VCMPacket& packet,
int64_t timeInMs,
bool enableDecodableState,
VCMDecodeErrorMode decode_error_mode,
const FrameData& frame_data);
// State

View File

@ -168,7 +168,7 @@ VCMJitterBuffer::VCMJitterBuffer(Clock* clock,
max_nack_list_size_(0),
max_packet_age_to_nack_(0),
max_incomplete_time_ms_(0),
decode_with_errors_(false),
decode_error_mode_(kNoErrors),
average_packets_per_frame_(0.0f),
frame_counter_(0) {
memset(frame_buffers_, 0, sizeof(frame_buffers_));
@ -215,7 +215,7 @@ void VCMJitterBuffer::CopyFrom(const VCMJitterBuffer& rhs) {
first_packet_since_reset_ = rhs.first_packet_since_reset_;
last_decoded_state_ = rhs.last_decoded_state_;
num_not_decodable_packets_ = rhs.num_not_decodable_packets_;
decode_with_errors_ = rhs.decode_with_errors_;
decode_error_mode_ = rhs.decode_error_mode_;
assert(max_nack_list_size_ == rhs.max_nack_list_size_);
assert(max_packet_age_to_nack_ == rhs.max_packet_age_to_nack_);
assert(max_incomplete_time_ms_ == rhs.max_incomplete_time_ms_);
@ -491,7 +491,7 @@ bool VCMJitterBuffer::NextMaybeIncompleteTimestamp(uint32_t* timestamp) {
if (!running_) {
return false;
}
if (!decode_with_errors_) {
if (decode_error_mode_ == kNoErrors) {
// No point to continue, as we are not decoding with errors.
return false;
}
@ -502,8 +502,8 @@ bool VCMJitterBuffer::NextMaybeIncompleteTimestamp(uint32_t* timestamp) {
if (!oldest_frame) {
return false;
}
if (decodable_frames_.empty() && incomplete_frames_.size() <= 1 &&
oldest_frame->GetState() == kStateIncomplete) {
if (decodable_frames_.empty() && incomplete_frames_.size() <= 1
&& oldest_frame->GetState() != kStateComplete) {
// If we have only one frame in the buffer, release it only if it is
// complete.
return false;
@ -704,8 +704,9 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
FrameData frame_data;
frame_data.rtt_ms = rtt_ms_;
frame_data.rolling_average_packets_per_frame = average_packets_per_frame_;
buffer_return = frame->InsertPacket(packet, now_ms,
decode_with_errors_,
buffer_return = frame->InsertPacket(packet,
now_ms,
decode_error_mode_,
frame_data);
if (!frame->GetCountedFrame()) {
TRACE_EVENT_ASYNC_BEGIN1("webrtc", "Video", frame->TimeStamp(),
@ -802,9 +803,12 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet,
bool VCMJitterBuffer::IsContinuousInState(const VCMFrameBuffer& frame,
const VCMDecodingState& decoding_state) const {
// Is this frame complete or decodable and continuous?
// Is this frame (complete or decodable) and continuous?
// kStateDecodable will never be set when decode_error_mode_ is false
// as SessionInfo determines this state based on the error mode (and frame
// completeness).
if ((frame.GetState() == kStateComplete ||
(decode_with_errors_ && frame.GetState() == kStateDecodable)) &&
frame.GetState() == kStateDecodable) &&
decoding_state.ContinuousFrame(&frame)) {
return true;
} else {

View File

@ -17,6 +17,7 @@
#include <vector>
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
#include "webrtc/modules/video_coding/main/source/decoding_state.h"
#include "webrtc/modules/video_coding/main/source/inter_frame_delay.h"
@ -175,9 +176,11 @@ class VCMJitterBuffer {
uint16_t* GetNackList(uint16_t* nack_list_size, bool* request_key_frame);
// Enable/disable decoding with errors.
void DecodeWithErrors(bool enable) {decode_with_errors_ = enable;}
// TODO(agalusza): Add logic for handling kSelectiveErrors.
void DecodeErrorMode(VCMDecodeErrorMode error_mode)
{decode_error_mode_ = error_mode;}
int64_t LastDecodedTimestamp() const;
bool decode_with_errors() const {return decode_with_errors_;}
VCMDecodeErrorMode decode_error_mode() const {return decode_error_mode_;}
// Used to compute time of complete continuous frames. Returns the timestamps
// corresponding to the start and end of the continuous complete buffer.
@ -330,7 +333,7 @@ class VCMJitterBuffer {
int max_packet_age_to_nack_; // Measured in sequence numbers.
int max_incomplete_time_ms_;
bool decode_with_errors_;
VCMDecodeErrorMode decode_error_mode_;
// Estimated rolling average of packets per frame
float average_packets_per_frame_;
// average_packets_per_frame converges fast if we have fewer than this many

View File

@ -243,7 +243,7 @@ TEST_F(TestBasicJitterBuffer, StopRunning) {
EXPECT_TRUE(NULL == DecodeIncompleteFrame());
jitter_buffer_->Start();
// Allow decoding with errors.
jitter_buffer_->DecodeWithErrors(true);
jitter_buffer_->DecodeErrorMode(kWithErrors);
// No packets inserted.
EXPECT_TRUE(NULL == DecodeCompleteFrame());
@ -573,7 +573,7 @@ TEST_F(TestBasicJitterBuffer, PacketLoss) {
// 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_->DecodeWithErrors(true);
jitter_buffer_->DecodeErrorMode(kWithErrors);
seq_num_ = 0xffff - 4;
seq_num_++;
packet_->frameType = kVideoFrameKey;
@ -586,7 +586,6 @@ TEST_F(TestBasicJitterBuffer, PacketLoss) {
bool retransmitted = false;
EXPECT_EQ(kFirstPacket, jitter_buffer_->InsertPacket(*packet_,
&retransmitted));
int insert_return_val;
for (int i = 0; i < 11; ++i) {
webrtc::FrameType frametype = kVideoFrameDelta;
seq_num_++;
@ -612,9 +611,8 @@ TEST_F(TestBasicJitterBuffer, PacketLoss) {
packet_->seqNum = seq_num_;
packet_->completeNALU = kNaluEnd;
insert_return_val = jitter_buffer_->InsertPacket(*packet_, &retransmitted);
EXPECT_TRUE(insert_return_val == kIncomplete
|| insert_return_val == kDecodableSession);
EXPECT_EQ(jitter_buffer_->InsertPacket(*packet_, &retransmitted),
kDecodableSession);
// Insert an empty (non-media) packet.
seq_num_++;
@ -624,9 +622,8 @@ TEST_F(TestBasicJitterBuffer, PacketLoss) {
packet_->completeNALU = kNaluEnd;
packet_->frameType = kFrameEmpty;
insert_return_val = jitter_buffer_->InsertPacket(*packet_, &retransmitted);
EXPECT_TRUE(insert_return_val == kIncomplete
|| insert_return_val == kDecodableSession);
EXPECT_EQ(jitter_buffer_->InsertPacket(*packet_, &retransmitted),
kDecodableSession);
frame_out = DecodeIncompleteFrame();
@ -1098,7 +1095,7 @@ TEST_F(TestBasicJitterBuffer, ExceedNumOfFrameWithSeqNumWrap) {
}
TEST_F(TestBasicJitterBuffer, EmptyLastFrame) {
jitter_buffer_->DecodeWithErrors(true);
jitter_buffer_->DecodeErrorMode(kWithErrors);
seq_num_ = 3;
// Insert one empty packet per frame, should never return the last timestamp
// inserted. Only return empty frames in the presence of subsequent frames.
@ -1125,7 +1122,7 @@ TEST_F(TestBasicJitterBuffer, EmptyLastFrame) {
TEST_F(TestBasicJitterBuffer, H264IncompleteNalu) {
jitter_buffer_->SetNackMode(kNoNack, -1, -1);
jitter_buffer_->DecodeWithErrors(true);
jitter_buffer_->DecodeErrorMode(kWithErrors);
seq_num_ ++;
timestamp_ += 33 * 90;
int insertedLength = 0;
@ -1147,7 +1144,7 @@ TEST_F(TestBasicJitterBuffer, H264IncompleteNalu) {
packet_->completeNALU = kNaluIncomplete;
packet_->markerBit = false;
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
EXPECT_EQ(kDecodableSession, jitter_buffer_->InsertPacket(*packet_,
&retransmitted));
seq_num_++;
@ -1157,14 +1154,14 @@ TEST_F(TestBasicJitterBuffer, H264IncompleteNalu) {
packet_->completeNALU = kNaluEnd;
packet_->markerBit = false;
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
EXPECT_EQ(kDecodableSession, jitter_buffer_->InsertPacket(*packet_,
&retransmitted));
seq_num_++;
packet_->seqNum = seq_num_;
packet_->completeNALU = kNaluComplete;
packet_->markerBit = true; // Last packet
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*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
@ -1213,7 +1210,7 @@ TEST_F(TestBasicJitterBuffer, H264IncompleteNalu) {
packet_->isFirstPacket = true;
packet_->completeNALU = kNaluStart;
packet_->markerBit = false;
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
EXPECT_EQ(kDecodableSession, jitter_buffer_->InsertPacket(*packet_,
&retransmitted));
insertedLength += packet_->sizeBytes; // This packet should be decoded.
@ -1224,7 +1221,7 @@ TEST_F(TestBasicJitterBuffer, H264IncompleteNalu) {
packet_->isFirstPacket = false;
packet_->completeNALU = kNaluComplete;
packet_->markerBit = false;
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
EXPECT_EQ(kDecodableSession, jitter_buffer_->InsertPacket(*packet_,
&retransmitted));
insertedLength += packet_->sizeBytes; // This packet should be decoded.
@ -1235,7 +1232,7 @@ TEST_F(TestBasicJitterBuffer, H264IncompleteNalu) {
packet_->isFirstPacket = false;
packet_->completeNALU = kNaluStart;
packet_->markerBit = false;
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
EXPECT_EQ(kDecodableSession, jitter_buffer_->InsertPacket(*packet_,
&retransmitted));
// This packet should be decoded since it's the beginning of a NAL.
insertedLength += packet_->sizeBytes;
@ -1247,7 +1244,7 @@ TEST_F(TestBasicJitterBuffer, H264IncompleteNalu) {
packet_->isFirstPacket = false;
packet_->completeNALU = kNaluEnd;
packet_->markerBit = true;
EXPECT_EQ(kIncomplete, jitter_buffer_->InsertPacket(*packet_,
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.
@ -1311,7 +1308,7 @@ TEST_F(TestBasicJitterBuffer, NextFrameWhenIncomplete) {
// 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
// timestamp.
jitter_buffer_->DecodeWithErrors(true);
jitter_buffer_->DecodeErrorMode(kWithErrors);
// Start with a complete key frame - insert and decode.
packet_->frameType = kVideoFrameKey;
packet_->isFirstPacket = true;
@ -1686,7 +1683,7 @@ TEST_F(TestJitterBufferNack, UseNackToRecoverFirstKeyFrameSecondInQueue) {
TEST_F(TestJitterBufferNack, NormalOperation) {
EXPECT_EQ(kNack, jitter_buffer_->nack_mode());
jitter_buffer_->DecodeWithErrors(true);
jitter_buffer_->DecodeErrorMode(kWithErrors);
EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError);
EXPECT_TRUE(DecodeIncompleteFrame());
@ -1702,12 +1699,12 @@ TEST_F(TestJitterBufferNack, NormalOperation) {
EXPECT_FALSE(DecodeCompleteFrame());
while (stream_generator_->PacketsRemaining() > 1) {
if (stream_generator_->NextSequenceNumber() % 10 != 0) {
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
EXPECT_EQ(kDecodableSession, InsertPacketAndPop(0));
} else {
stream_generator_->NextPacket(NULL); // Drop packet
}
}
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
EXPECT_EQ(kDecodableSession, InsertPacketAndPop(0));
EXPECT_EQ(0, stream_generator_->PacketsRemaining());
EXPECT_FALSE(DecodeCompleteFrame());
EXPECT_FALSE(DecodeIncompleteFrame());

View File

@ -12,7 +12,6 @@
#include <assert.h>
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/modules/video_coding/main/source/encoded_frame.h"
#include "webrtc/modules/video_coding/main/source/internal_defines.h"
#include "webrtc/modules/video_coding/main/source/media_opt_util.h"
@ -314,14 +313,15 @@ VCMReceiverState VCMReceiver::State() const {
return state_;
}
void VCMReceiver::SetDecodeWithErrors(bool enable){
void VCMReceiver::SetDecodeErrorMode(
VCMDecodeErrorMode decode_error_mode) {
CriticalSectionScoped cs(crit_sect_);
jitter_buffer_.DecodeWithErrors(enable);
jitter_buffer_.DecodeErrorMode(decode_error_mode);
}
bool VCMReceiver::DecodeWithErrors() const {
VCMDecodeErrorMode VCMReceiver::DecodeErrorMode() const {
CriticalSectionScoped cs(crit_sect_);
return jitter_buffer_.decode_with_errors();
return jitter_buffer_.decode_error_mode();
}
int VCMReceiver::SetMinReceiverDelay(int desired_delay_ms) {

View File

@ -15,6 +15,8 @@
#include "webrtc/modules/video_coding/main/source/packet.h"
#include "webrtc/modules/video_coding/main/source/timing.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
namespace webrtc {
@ -78,8 +80,8 @@ class VCMReceiver {
int SetMinReceiverDelay(int desired_delay_ms);
// Decoding with errors.
void SetDecodeWithErrors(bool enable);
bool DecodeWithErrors() const;
void SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode);
VCMDecodeErrorMode DecodeErrorMode() const;
// Returns size in time (milliseconds) of complete continuous frames in the
// jitter buffer. The render time is estimated based on the render delay at

View File

@ -392,7 +392,7 @@ VCMSessionInfo::session_nack() const {
int VCMSessionInfo::InsertPacket(const VCMPacket& packet,
uint8_t* frame_buffer,
bool enable_decodable_state,
VCMDecodeErrorMode decode_error_mode,
const FrameData& frame_data) {
// Check if this is first packet (only valid for some codecs)
if (packet.isFirstPacket) {
@ -429,8 +429,11 @@ int VCMSessionInfo::InsertPacket(const VCMPacket& packet,
int returnLength = InsertBuffer(frame_buffer, packet_list_it);
UpdateCompleteSession();
if (enable_decodable_state)
if (decode_error_mode == kWithErrors)
decodable_ = true;
else if (decode_error_mode == kSelectiveErrors)
UpdateDecodableSession(frame_data);
return returnLength;
}

View File

@ -14,6 +14,7 @@
#include <list>
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/modules/video_coding/main/source/packet.h"
#include "webrtc/typedefs.h"
@ -47,7 +48,7 @@ class VCMSessionInfo {
void Reset();
int InsertPacket(const VCMPacket& packet,
uint8_t* frame_buffer,
bool enable_decodable_state,
VCMDecodeErrorMode enable_decodable_state,
const FrameData& frame_data);
bool complete() const;
bool decodable() const;

View File

@ -154,7 +154,10 @@ TEST_F(TestSessionInfo, TestSimpleAPIs) {
packet_.frameType = kVideoFrameKey;
FillPacket(0);
ASSERT_EQ(packet_buffer_size(),
session_.InsertPacket(packet_, frame_buffer_, false, frame_data));
session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data));
EXPECT_FALSE(session_.HaveLastPacket());
EXPECT_EQ(kVideoFrameKey, session_.FrameType());
@ -162,7 +165,10 @@ TEST_F(TestSessionInfo, TestSimpleAPIs) {
packet_.markerBit = true;
packet_.seqNum += 1;
ASSERT_EQ(packet_buffer_size(),
session_.InsertPacket(packet_, frame_buffer_, false, frame_data));
session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data));
EXPECT_TRUE(session_.HaveLastPacket());
EXPECT_EQ(packet_.seqNum, session_.HighSequenceNumber());
EXPECT_EQ(0xFFFE, session_.LowSequenceNumber());
@ -175,7 +181,10 @@ TEST_F(TestSessionInfo, TestSimpleAPIs) {
packet_.sizeBytes = 0;
packet_.frameType = kFrameEmpty;
ASSERT_EQ(0,
session_.InsertPacket(packet_, frame_buffer_, false, frame_data));
session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data));
EXPECT_EQ(packet_.seqNum, session_.HighSequenceNumber());
}
@ -184,21 +193,30 @@ TEST_F(TestSessionInfo, NormalOperation) {
packet_.isFirstPacket = true;
packet_.markerBit = false;
FillPacket(0);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
packet_.isFirstPacket = false;
for (int i = 1; i < 9; ++i) {
packet_.seqNum += 1;
FillPacket(i);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
}
packet_.seqNum += 1;
packet_.markerBit = true;
FillPacket(9);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
EXPECT_EQ(0, session_.packets_not_decodable());
@ -220,7 +238,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsOneLoss) {
FillPacket(0);
VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -231,7 +252,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsOneLoss) {
packet_header_.header.sequenceNumber += 2;
FillPacket(2);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -242,7 +266,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsOneLoss) {
packet_header_.header.sequenceNumber += 1;
FillPacket(3);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -268,7 +295,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsOneLoss2) {
FillPacket(1);
VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -279,7 +309,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsOneLoss2) {
packet_header_.header.sequenceNumber += 1;
FillPacket(2);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -290,7 +323,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsOneLoss2) {
packet_header_.header.sequenceNumber += 1;
FillPacket(3);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -301,7 +337,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsOneLoss2) {
packet_header_.header.sequenceNumber += 2;
FillPacket(5);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -328,7 +367,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsNoLossWrap) {
FillPacket(0);
VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -339,7 +381,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsNoLossWrap) {
packet_header_.header.sequenceNumber += 1;
FillPacket(1);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -350,7 +395,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsNoLossWrap) {
packet_header_.header.sequenceNumber += 1;
FillPacket(2);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -361,7 +409,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsNoLossWrap) {
packet_header_.header.sequenceNumber += 1;
FillPacket(3);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -388,7 +439,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsLossWrap) {
FillPacket(0);
VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -399,7 +453,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsLossWrap) {
packet_header_.header.sequenceNumber += 1;
FillPacket(1);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -410,7 +467,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsLossWrap) {
packet_header_.header.sequenceNumber += 1;
FillPacket(2);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -421,7 +481,10 @@ TEST_F(TestVP8Partitions, TwoPartitionsLossWrap) {
packet_header_.header.sequenceNumber += 2;
FillPacket(3);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -449,7 +512,10 @@ TEST_F(TestVP8Partitions, ThreePartitionsOneMissing) {
FillPacket(1);
VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -460,7 +526,10 @@ TEST_F(TestVP8Partitions, ThreePartitionsOneMissing) {
packet_header_.header.sequenceNumber += 1;
FillPacket(2);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -471,7 +540,10 @@ TEST_F(TestVP8Partitions, ThreePartitionsOneMissing) {
packet_header_.header.sequenceNumber += 3;
FillPacket(5);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -482,7 +554,10 @@ TEST_F(TestVP8Partitions, ThreePartitionsOneMissing) {
packet_header_.header.sequenceNumber += 1;
FillPacket(6);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -509,7 +584,10 @@ TEST_F(TestVP8Partitions, ThreePartitionsLossInSecond) {
FillPacket(1);
VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -521,7 +599,10 @@ TEST_F(TestVP8Partitions, ThreePartitionsLossInSecond) {
FillPacket(2);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -532,7 +613,10 @@ TEST_F(TestVP8Partitions, ThreePartitionsLossInSecond) {
packet_header_.header.sequenceNumber += 2;
FillPacket(4);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -543,7 +627,10 @@ TEST_F(TestVP8Partitions, ThreePartitionsLossInSecond) {
packet_header_.header.sequenceNumber += 1;
FillPacket(5);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -554,7 +641,10 @@ TEST_F(TestVP8Partitions, ThreePartitionsLossInSecond) {
packet_header_.header.sequenceNumber += 1;
FillPacket(6);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -565,7 +655,10 @@ TEST_F(TestVP8Partitions, ThreePartitionsLossInSecond) {
packet_header_.header.sequenceNumber += 1;
FillPacket(7);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -592,7 +685,10 @@ TEST_F(TestVP8Partitions, AggregationOverTwoPackets) {
FillPacket(0);
VCMPacket* packet = new VCMPacket(packet_buffer_, packet_buffer_size(),
packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -603,7 +699,10 @@ TEST_F(TestVP8Partitions, AggregationOverTwoPackets) {
packet_header_.header.sequenceNumber += 1;
FillPacket(1);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -614,7 +713,10 @@ TEST_F(TestVP8Partitions, AggregationOverTwoPackets) {
packet_header_.header.sequenceNumber += 1;
FillPacket(2);
packet = new VCMPacket(packet_buffer_, packet_buffer_size(), packet_header_);
ASSERT_EQ(session_.InsertPacket(*packet, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(*packet,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
delete packet;
@ -640,8 +742,10 @@ TEST_F(TestNalUnits, OnlyReceivedEmptyPacket) {
packet_.sizeBytes = 0;
packet_.seqNum = 0;
packet_.markerBit = false;
ASSERT_EQ(0,
session_.InsertPacket(packet_, frame_buffer_, false, frame_data));
ASSERT_EQ(0, session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data));
EXPECT_EQ(0, session_.MakeDecodable());
EXPECT_EQ(0, session_.SessionLength());
@ -654,7 +758,10 @@ TEST_F(TestNalUnits, OneIsolatedNaluLoss) {
packet_.seqNum = 0;
packet_.markerBit = false;
FillPacket(0);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
packet_.isFirstPacket = false;
@ -662,7 +769,10 @@ TEST_F(TestNalUnits, OneIsolatedNaluLoss) {
packet_.seqNum += 2;
packet_.markerBit = true;
FillPacket(2);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
EXPECT_EQ(0, session_.MakeDecodable());
@ -680,7 +790,10 @@ TEST_F(TestNalUnits, LossInMiddleOfNalu) {
packet_.seqNum = 0;
packet_.markerBit = false;
FillPacket(0);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
packet_.isFirstPacket = false;
@ -688,7 +801,10 @@ TEST_F(TestNalUnits, LossInMiddleOfNalu) {
packet_.seqNum += 2;
packet_.markerBit = true;
FillPacket(2);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
EXPECT_EQ(packet_buffer_size(), session_.MakeDecodable());
@ -704,7 +820,10 @@ TEST_F(TestNalUnits, StartAndEndOfLastNalUnitLost) {
packet_.seqNum = 0;
packet_.markerBit = false;
FillPacket(0);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
packet_.isFirstPacket = false;
@ -712,7 +831,10 @@ TEST_F(TestNalUnits, StartAndEndOfLastNalUnitLost) {
packet_.seqNum += 2;
packet_.markerBit = false;
FillPacket(1);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
EXPECT_EQ(packet_buffer_size(), session_.MakeDecodable());
@ -729,7 +851,10 @@ TEST_F(TestNalUnits, ReorderWrapNoLoss) {
packet_.seqNum += 1;
packet_.markerBit = false;
FillPacket(1);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
packet_.isFirstPacket = true;
@ -737,7 +862,10 @@ TEST_F(TestNalUnits, ReorderWrapNoLoss) {
packet_.seqNum -= 1;
packet_.markerBit = false;
FillPacket(0);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
packet_.isFirstPacket = false;
@ -745,7 +873,10 @@ TEST_F(TestNalUnits, ReorderWrapNoLoss) {
packet_.seqNum += 2;
packet_.markerBit = true;
FillPacket(2);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
EXPECT_EQ(0, session_.MakeDecodable());
@ -761,7 +892,10 @@ TEST_F(TestNalUnits, WrapLosses) {
packet_.completeNALU = kNaluIncomplete;
packet_.markerBit = false;
FillPacket(1);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
packet_.isFirstPacket = false;
@ -769,7 +903,10 @@ TEST_F(TestNalUnits, WrapLosses) {
packet_.seqNum += 2;
packet_.markerBit = true;
FillPacket(2);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
EXPECT_EQ(2 * packet_buffer_size(), session_.MakeDecodable());
@ -785,7 +922,10 @@ TEST_F(TestNalUnits, ReorderWrapLosses) {
packet_.seqNum += 2;
packet_.markerBit = true;
FillPacket(2);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
packet_.seqNum -= 2;
@ -793,7 +933,10 @@ TEST_F(TestNalUnits, ReorderWrapLosses) {
packet_.completeNALU = kNaluIncomplete;
packet_.markerBit = false;
FillPacket(1);
ASSERT_EQ(session_.InsertPacket(packet_, frame_buffer_, false, frame_data),
ASSERT_EQ(session_.InsertPacket(packet_,
frame_buffer_,
kNoErrors,
frame_data),
packet_buffer_size());
EXPECT_EQ(2 * packet_buffer_size(), session_.MakeDecodable());

File diff suppressed because it is too large Load Diff

View File

@ -262,12 +262,16 @@ public:
// Set the receiver robustness mode.
virtual int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,
DecodeErrors errorMode);
VCMDecodeErrorMode errorMode);
virtual void SetNackSettings(size_t max_nack_list_size,
int max_packet_age_to_nack,
int max_incomplete_time_ms);
// Sets jitter buffer decode error mode.
void SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode);
// Set the video delay for the receiver (default = 0).
virtual int SetMinReceiverDelay(int desired_delay_ms);

View File

@ -102,7 +102,7 @@ TEST_F(VCMRobustnessTest, TestHardNack) {
ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode(
VideoCodingModule::kHardNack,
VideoCodingModule::kNoDecodeErrors));
kNoErrors));
InsertPacket(0, 0, true, false, kVideoFrameKey);
InsertPacket(0, 1, false, false, kVideoFrameKey);
@ -146,7 +146,7 @@ TEST_F(VCMRobustnessTest, TestHardNackNoneDecoded) {
ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode(
VideoCodingModule::kHardNack,
VideoCodingModule::kNoDecodeErrors));
kNoErrors));
InsertPacket(3000, 3, true, false, kVideoFrameDelta);
InsertPacket(3000, 4, false, false, kVideoFrameDelta);
@ -216,7 +216,7 @@ TEST_F(VCMRobustnessTest, TestDualDecoder) {
ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode(
VideoCodingModule::kDualDecoder,
VideoCodingModule::kAllowDecodeErrors));
kWithErrors));
InsertPacket(0, 0, true, false, kVideoFrameKey);
InsertPacket(0, 1, false, false, kVideoFrameKey);
@ -297,7 +297,7 @@ TEST_F(VCMRobustnessTest, TestModeNoneWithErrors) {
ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode(
VideoCodingModule::kNone,
VideoCodingModule::kAllowDecodeErrors));
kWithErrors));
InsertPacket(0, 0, true, false, kVideoFrameKey);
InsertPacket(0, 1, false, false, kVideoFrameKey);