diff --git a/webrtc/modules/video_coding/main/interface/video_coding.h b/webrtc/modules/video_coding/main/interface/video_coding.h index 53c92f63d..9f6876f8e 100644 --- a/webrtc/modules/video_coding/main/interface/video_coding.h +++ b/webrtc/modules/video_coding/main/interface/video_coding.h @@ -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: @@ -257,7 +270,7 @@ public: // Return value : VCM_OK, on success. // < 0, on error. virtual int32_t SetVideoProtection(VCMVideoProtection videoProtection, - bool enable) = 0; + bool enable) = 0; // Add one raw video frame to the encoder. This function does all the necessary // processing, then decides what frame type to encode, or if the frame should be @@ -324,8 +337,8 @@ public: // Return value : VCM_OK, on success. // < 0, on error. virtual int32_t RegisterReceiveCodec(const VideoCodec* receiveCodec, - int32_t numberOfCores, - bool requireKeyFrame = false) = 0; + int32_t numberOfCores, + bool requireKeyFrame = false) = 0; // Register an externally defined decoder/renderer object. Can be a decoder only or a // decoder coupled with a renderer. Note that RegisterReceiveCodec must be called to @@ -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 diff --git a/webrtc/modules/video_coding/main/source/decoding_state_unittest.cc b/webrtc/modules/video_coding/main/source/decoding_state_unittest.cc index 04846f7c2..ccfe79864 100644 --- a/webrtc/modules/video_coding/main/source/decoding_state_unittest.cc +++ b/webrtc/modules/video_coding/main/source/decoding_state_unittest.cc @@ -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)); diff --git a/webrtc/modules/video_coding/main/source/frame_buffer.cc b/webrtc/modules/video_coding/main/source/frame_buffer.cc index 6d4be4aa6..167b05267 100644 --- a/webrtc/modules/video_coding/main/source/frame_buffer.cc +++ b/webrtc/modules/video_coding/main/source/frame_buffer.cc @@ -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; diff --git a/webrtc/modules/video_coding/main/source/frame_buffer.h b/webrtc/modules/video_coding/main/source/frame_buffer.h index bad333c06..8bd969016 100644 --- a/webrtc/modules/video_coding/main/source/frame_buffer.h +++ b/webrtc/modules/video_coding/main/source/frame_buffer.h @@ -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 diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer.cc b/webrtc/modules/video_coding/main/source/jitter_buffer.cc index 09d5a31c6..add2ec322 100644 --- a/webrtc/modules/video_coding/main/source/jitter_buffer.cc +++ b/webrtc/modules/video_coding/main/source/jitter_buffer.cc @@ -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 { diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer.h b/webrtc/modules/video_coding/main/source/jitter_buffer.h index 4aeddfedd..ab429a7fe 100644 --- a/webrtc/modules/video_coding/main/source/jitter_buffer.h +++ b/webrtc/modules/video_coding/main/source/jitter_buffer.h @@ -17,6 +17,7 @@ #include #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 diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc b/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc index 7af715a02..1020aaac2 100644 --- a/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc +++ b/webrtc/modules/video_coding/main/source/jitter_buffer_unittest.cc @@ -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()); diff --git a/webrtc/modules/video_coding/main/source/receiver.cc b/webrtc/modules/video_coding/main/source/receiver.cc index 4cbbebd31..3c97001b3 100644 --- a/webrtc/modules/video_coding/main/source/receiver.cc +++ b/webrtc/modules/video_coding/main/source/receiver.cc @@ -12,7 +12,6 @@ #include -#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) { diff --git a/webrtc/modules/video_coding/main/source/receiver.h b/webrtc/modules/video_coding/main/source/receiver.h index aeeb7ac1b..ac510ea22 100644 --- a/webrtc/modules/video_coding/main/source/receiver.h +++ b/webrtc/modules/video_coding/main/source/receiver.h @@ -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 diff --git a/webrtc/modules/video_coding/main/source/session_info.cc b/webrtc/modules/video_coding/main/source/session_info.cc index a95b26c85..d524b99ac 100644 --- a/webrtc/modules/video_coding/main/source/session_info.cc +++ b/webrtc/modules/video_coding/main/source/session_info.cc @@ -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; } diff --git a/webrtc/modules/video_coding/main/source/session_info.h b/webrtc/modules/video_coding/main/source/session_info.h index 79b70600e..708a48aff 100644 --- a/webrtc/modules/video_coding/main/source/session_info.h +++ b/webrtc/modules/video_coding/main/source/session_info.h @@ -14,6 +14,7 @@ #include #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; diff --git a/webrtc/modules/video_coding/main/source/session_info_unittest.cc b/webrtc/modules/video_coding/main/source/session_info_unittest.cc index e8fdfe86e..5d4bf4884 100644 --- a/webrtc/modules/video_coding/main/source/session_info_unittest.cc +++ b/webrtc/modules/video_coding/main/source/session_info_unittest.cc @@ -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()); diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.cc b/webrtc/modules/video_coding/main/source/video_coding_impl.cc index df798cc9f..d7a3b15e5 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.cc +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.cc @@ -19,20 +19,17 @@ #include "webrtc/system_wrappers/interface/trace.h" #include "webrtc/system_wrappers/interface/trace_event.h" -namespace webrtc -{ +namespace webrtc { -//#define DEBUG_DECODER_BIT_STREAM +// #define DEBUG_DECODER_BIT_STREAM uint32_t -VCMProcessTimer::Period() const -{ +VCMProcessTimer::Period() const { return _periodMs; } uint32_t -VCMProcessTimer::TimeUntilProcess() const -{ +VCMProcessTimer::TimeUntilProcess() const { const int64_t time_since_process = _clock->TimeInMilliseconds() - static_cast(_latestMs); const int64_t time_until_process = static_cast(_periodMs) - @@ -43,8 +40,7 @@ VCMProcessTimer::TimeUntilProcess() const } void -VCMProcessTimer::Processed() -{ +VCMProcessTimer::Processed() { _latestMs = _clock->TimeInMilliseconds(); } @@ -98,10 +94,8 @@ VideoCodingModuleImpl::VideoCodingModuleImpl(const int32_t id, #endif } -VideoCodingModuleImpl::~VideoCodingModuleImpl() -{ - if (_dualDecoder != NULL) - { +VideoCodingModuleImpl::~VideoCodingModuleImpl() { + if (_dualDecoder != NULL) { _codecDataBase.ReleaseDecoder(_dualDecoder); } delete _receiveCritSect; @@ -112,48 +106,40 @@ VideoCodingModuleImpl::~VideoCodingModuleImpl() #ifdef DEBUG_DECODER_BIT_STREAM fclose(_bitStreamBeforeDecoder); #endif - if (_encoderInputFile != NULL) - { + if (_encoderInputFile != NULL) { fclose(_encoderInputFile); } } VideoCodingModule* -VideoCodingModule::Create(const int32_t id) -{ +VideoCodingModule::Create(const int32_t id) { return new VideoCodingModuleImpl(id, Clock::GetRealTimeClock(), new EventFactoryImpl, true); } VideoCodingModule* VideoCodingModule::Create(const int32_t id, Clock* clock, - EventFactory* event_factory) -{ + EventFactory* event_factory) { assert(clock); assert(event_factory); return new VideoCodingModuleImpl(id, clock, event_factory, false); } void -VideoCodingModule::Destroy(VideoCodingModule* module) -{ - if (module != NULL) - { +VideoCodingModule::Destroy(VideoCodingModule* module) { + if (module != NULL) { delete static_cast(module); } } int32_t -VideoCodingModuleImpl::Process() -{ +VideoCodingModuleImpl::Process() { int32_t returnValue = VCM_OK; // Receive-side statistics - if (_receiveStatsTimer.TimeUntilProcess() == 0) - { + if (_receiveStatsTimer.TimeUntilProcess() == 0) { _receiveStatsTimer.Processed(); - if (_receiveStatsCallback != NULL) - { + if (_receiveStatsCallback != NULL) { uint32_t bitRate; uint32_t frameRate; _receiver.ReceiveStatistics(&bitRate, &frameRate); @@ -168,11 +154,9 @@ VideoCodingModuleImpl::Process() } // Send-side statistics - if (_sendStatsTimer.TimeUntilProcess() == 0) - { + if (_sendStatsTimer.TimeUntilProcess() == 0) { _sendStatsTimer.Processed(); - if (_sendStatsCallback != NULL) - { + if (_sendStatsCallback != NULL) { uint32_t bitRate; uint32_t frameRate; { @@ -187,11 +171,9 @@ VideoCodingModuleImpl::Process() // Packet retransmission requests // TODO(holmer): Add API for changing Process interval and make sure it's // disabled when NACK is off. - if (_retransmissionTimer.TimeUntilProcess() == 0) - { + if (_retransmissionTimer.TimeUntilProcess() == 0) { _retransmissionTimer.Processed(); - if (_packetRequestCallback != NULL) - { + if (_packetRequestCallback != NULL) { uint16_t length; { CriticalSectionScoped cs(_receiveCritSect); @@ -199,26 +181,21 @@ VideoCodingModuleImpl::Process() } std::vector nackList(length); const int32_t ret = NackList(&nackList[0], length); - if (ret != VCM_OK && returnValue == VCM_OK) - { + if (ret != VCM_OK && returnValue == VCM_OK) { returnValue = ret; } - if (length > 0) - { + if (length > 0) { _packetRequestCallback->ResendPackets(&nackList[0], length); } } } // Key frame requests - if (_keyRequestTimer.TimeUntilProcess() == 0) - { + if (_keyRequestTimer.TimeUntilProcess() == 0) { _keyRequestTimer.Processed(); - if (_scheduleKeyRequest && _frameTypeCallback != NULL) - { + if (_scheduleKeyRequest && _frameTypeCallback != NULL) { const int32_t ret = RequestKeyFrame(); - if (ret != VCM_OK && returnValue == VCM_OK) - { + if (ret != VCM_OK && returnValue == VCM_OK) { returnValue = ret; } } @@ -228,8 +205,7 @@ VideoCodingModuleImpl::Process() } int32_t -VideoCodingModuleImpl::Id() const -{ +VideoCodingModuleImpl::Id() const { CriticalSectionScoped receiveCs(_receiveCritSect); { CriticalSectionScoped sendCs(_sendCritSect); @@ -239,8 +215,7 @@ VideoCodingModuleImpl::Id() const // Change the unique identifier of this object int32_t -VideoCodingModuleImpl::ChangeUniqueId(const int32_t id) -{ +VideoCodingModuleImpl::ChangeUniqueId(const int32_t id) { CriticalSectionScoped receiveCs(_receiveCritSect); { CriticalSectionScoped sendCs(_sendCritSect); @@ -252,14 +227,12 @@ VideoCodingModuleImpl::ChangeUniqueId(const int32_t id) // Returns the number of milliseconds until the module wants a worker thread to // call Process int32_t -VideoCodingModuleImpl::TimeUntilNextProcess() -{ +VideoCodingModuleImpl::TimeUntilNextProcess() { uint32_t timeUntilNextProcess = VCM_MIN( _receiveStatsTimer.TimeUntilProcess(), _sendStatsTimer.TimeUntilProcess()); if ((_receiver.NackMode() != kNoNack) || - (_dualReceiver.State() != kPassive)) - { + (_dualReceiver.State() != kPassive)) { // We need a Process call more often if we are relying on // retransmissions timeUntilNextProcess = VCM_MIN(timeUntilNextProcess, @@ -273,17 +246,14 @@ VideoCodingModuleImpl::TimeUntilNextProcess() // Get number of supported codecs uint8_t -VideoCodingModule::NumberOfCodecs() -{ +VideoCodingModule::NumberOfCodecs() { return VCMCodecDataBase::NumberOfCodecs(); } // Get supported codec with id int32_t -VideoCodingModule::Codec(uint8_t listId, VideoCodec* codec) -{ - if (codec == NULL) - { +VideoCodingModule::Codec(uint8_t listId, VideoCodec* codec) { + if (codec == NULL) { return VCM_PARAMETER_ERROR; } return VCMCodecDataBase::Codec(listId, codec) ? 0 : -1; @@ -291,10 +261,8 @@ VideoCodingModule::Codec(uint8_t listId, VideoCodec* codec) // Get supported codec with type int32_t -VideoCodingModule::Codec(VideoCodecType codecType, VideoCodec* codec) -{ - if (codec == NULL) - { +VideoCodingModule::Codec(VideoCodecType codecType, VideoCodec* codec) { + if (codec == NULL) { return VCM_PARAMETER_ERROR; } return VCMCodecDataBase::Codec(codecType, codec) ? 0 : -1; @@ -306,15 +274,14 @@ VideoCodingModule::Codec(VideoCodecType codecType, VideoCodec* codec) // Reset send side to initial state - all components int32_t -VideoCodingModuleImpl::InitializeSender() -{ +VideoCodingModuleImpl::InitializeSender() { CriticalSectionScoped cs(_sendCritSect); _codecDataBase.ResetSender(); _encoder = NULL; _encodedFrameCallback.SetTransportCallback(NULL); // setting default bitRate and frameRate to 0 _mediaOpt.SetEncodingData(kVideoCodecUnknown, 0, 0, 0, 0, 0, 0); - _mediaOpt.Reset(); // Resetting frame dropper + _mediaOpt.Reset(); // Resetting frame dropper return VCM_OK; } @@ -322,8 +289,7 @@ VideoCodingModuleImpl::InitializeSender() int32_t VideoCodingModuleImpl::RegisterSendCodec(const VideoCodec* sendCodec, uint32_t numberOfCores, - uint32_t maxPayloadSize) -{ + uint32_t maxPayloadSize) { CriticalSectionScoped cs(_sendCritSect); if (sendCodec == NULL) { return VCM_PARAMETER_ERROR; @@ -370,12 +336,10 @@ VideoCodingModuleImpl::RegisterSendCodec(const VideoCodec* sendCodec, // Get current send codec int32_t -VideoCodingModuleImpl::SendCodec(VideoCodec* currentSendCodec) const -{ +VideoCodingModuleImpl::SendCodec(VideoCodec* currentSendCodec) const { CriticalSectionScoped cs(_sendCritSect); - if (currentSendCodec == NULL) - { + if (currentSendCodec == NULL) { return VCM_PARAMETER_ERROR; } return _codecDataBase.SendCodec(currentSendCodec) ? 0 : -1; @@ -383,8 +347,7 @@ VideoCodingModuleImpl::SendCodec(VideoCodec* currentSendCodec) const // Get the current send codec type VideoCodecType -VideoCodingModuleImpl::SendCodec() const -{ +VideoCodingModuleImpl::SendCodec() const { CriticalSectionScoped cs(_sendCritSect); return _codecDataBase.SendCodec(); @@ -394,18 +357,15 @@ VideoCodingModuleImpl::SendCodec() const // This can not be used together with external decoder callbacks. int32_t VideoCodingModuleImpl::RegisterExternalEncoder(VideoEncoder* externalEncoder, - uint8_t payloadType, - bool internalSource /*= false*/) -{ + uint8_t payloadType, + bool internalSource /*= false*/) { CriticalSectionScoped cs(_sendCritSect); - if (externalEncoder == NULL) - { + if (externalEncoder == NULL) { bool wasSendCodec = false; const bool ret = _codecDataBase.DeregisterExternalEncoder( payloadType, &wasSendCodec); - if (wasSendCodec) - { + if (wasSendCodec) { // Make sure the VCM doesn't use the de-registered codec _encoder = NULL; } @@ -419,19 +379,16 @@ VideoCodingModuleImpl::RegisterExternalEncoder(VideoEncoder* externalEncoder, // Get codec config parameters int32_t VideoCodingModuleImpl::CodecConfigParameters(uint8_t* buffer, - int32_t size) -{ + int32_t size) { CriticalSectionScoped cs(_sendCritSect); - if (_encoder != NULL) - { + if (_encoder != NULL) { return _encoder->CodecConfigParameters(buffer, size); } return VCM_UNINITIALIZED; } // Get encode bitrate -int VideoCodingModuleImpl::Bitrate(unsigned int* bitrate) const -{ +int VideoCodingModuleImpl::Bitrate(unsigned int* bitrate) const { CriticalSectionScoped cs(_sendCritSect); // return the bit rate which the encoder is set to if (!_encoder) { @@ -442,8 +399,7 @@ int VideoCodingModuleImpl::Bitrate(unsigned int* bitrate) const } // Get encode frame rate -int VideoCodingModuleImpl::FrameRate(unsigned int* framerate) const -{ +int VideoCodingModuleImpl::FrameRate(unsigned int* framerate) const { CriticalSectionScoped cs(_sendCritSect); // input frame rate, not compensated if (!_encoder) { @@ -457,39 +413,32 @@ int VideoCodingModuleImpl::FrameRate(unsigned int* framerate) const int32_t VideoCodingModuleImpl::SetChannelParameters(uint32_t target_bitrate, uint8_t lossRate, - uint32_t rtt) -{ + uint32_t rtt) { int32_t ret = 0; { CriticalSectionScoped sendCs(_sendCritSect); uint32_t targetRate = _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt); - if (_encoder != NULL) - { + if (_encoder != NULL) { ret = _encoder->SetChannelParameters(lossRate, rtt); - if (ret < 0 ) - { + if (ret < 0) { return ret; } ret = (int32_t)_encoder->SetRates(targetRate, _mediaOpt.InputFrameRate()); - if (ret < 0) - { + if (ret < 0) { return ret; } - } - else - { + } else { return VCM_UNINITIALIZED; } // encoder - }// send side + } // send side return VCM_OK; } int32_t -VideoCodingModuleImpl::SetReceiveChannelParameters(uint32_t rtt) -{ +VideoCodingModuleImpl::SetReceiveChannelParameters(uint32_t rtt) { CriticalSectionScoped receiveCs(_receiveCritSect); _receiver.UpdateRtt(rtt); return 0; @@ -499,8 +448,7 @@ VideoCodingModuleImpl::SetReceiveChannelParameters(uint32_t rtt) // buffers int32_t VideoCodingModuleImpl::RegisterTransportCallback( - VCMPacketizationCallback* transport) -{ + VCMPacketizationCallback* transport) { CriticalSectionScoped cs(_sendCritSect); _encodedFrameCallback.SetMediaOpt(&_mediaOpt); _encodedFrameCallback.SetTransportCallback(transport); @@ -512,8 +460,7 @@ VideoCodingModuleImpl::RegisterTransportCallback( // average frame rate and bit rate. int32_t VideoCodingModuleImpl::RegisterSendStatisticsCallback( - VCMSendStatisticsCallback* sendStats) -{ + VCMSendStatisticsCallback* sendStats) { CriticalSectionScoped cs(_sendCritSect); _sendStatsCallback = sendStats; return VCM_OK; @@ -523,8 +470,7 @@ VideoCodingModuleImpl::RegisterSendStatisticsCallback( // rate/dimensions need to be updated for video quality optimization int32_t VideoCodingModuleImpl::RegisterVideoQMCallback( - VCMQMSettingsCallback* videoQMSettings) -{ + VCMQMSettingsCallback* videoQMSettings) { CriticalSectionScoped cs(_sendCritSect); return _mediaOpt.RegisterVideoQMCallback(videoQMSettings); } @@ -534,8 +480,7 @@ VideoCodingModuleImpl::RegisterVideoQMCallback( // requested FEC rate and NACK status (on/off). int32_t VideoCodingModuleImpl::RegisterProtectionCallback( - VCMProtectionCallback* protection) -{ + VCMProtectionCallback* protection) { CriticalSectionScoped cs(_sendCritSect); _mediaOpt.RegisterProtectionCallback(protection); return VCM_OK; @@ -547,15 +492,12 @@ VideoCodingModuleImpl::RegisterProtectionCallback( // behavior is desired, use the following API: SetReceiverRobustnessMode. int32_t VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection, - bool enable) -{ + bool enable) { // By default, do not decode with errors. - _receiver.SetDecodeWithErrors(false); + _receiver.SetDecodeErrorMode(kNoErrors); // The dual decoder should always be error free. - _dualReceiver.SetDecodeWithErrors(false); - switch (videoProtection) - { - + _dualReceiver.SetDecodeErrorMode(kNoErrors); + switch (videoProtection) { case kProtectionNack: { // Both send-side and receive-side @@ -574,13 +516,10 @@ VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection, case kProtectionNackReceiver: { CriticalSectionScoped cs(_receiveCritSect); - if (enable) - { + if (enable) { // Enable NACK and always wait for retransmits. _receiver.SetNackMode(kNack, -1, -1); - } - else - { + } else { _receiver.SetNackMode(kNoNack, -1, -1); } break; @@ -589,18 +528,15 @@ VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection, case kProtectionDualDecoder: { CriticalSectionScoped cs(_receiveCritSect); - if (enable) - { + if (enable) { // Enable NACK but don't wait for retransmissions and don't // add any extra delay. _receiver.SetNackMode(kNack, 0, 0); // Enable NACK and always wait for retransmissions and // compensate with extra delay. _dualReceiver.SetNackMode(kNack, -1, -1); - _receiver.SetDecodeWithErrors(true); - } - else - { + _receiver.SetDecodeErrorMode(kWithErrors); + } else { _dualReceiver.SetNackMode(kNoNack, -1, -1); } break; @@ -609,17 +545,12 @@ VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection, case kProtectionKeyOnLoss: { CriticalSectionScoped cs(_receiveCritSect); - if (enable) - { + if (enable) { _keyRequestMode = kKeyOnLoss; - _receiver.SetDecodeWithErrors(true); - } - else if (_keyRequestMode == kKeyOnLoss) - { - _keyRequestMode = kKeyOnError; // default mode - } - else - { + _receiver.SetDecodeErrorMode(kWithErrors); + } else if (_keyRequestMode == kKeyOnLoss) { + _keyRequestMode = kKeyOnError; // default mode + } else { return VCM_PARAMETER_ERROR; } break; @@ -628,16 +559,11 @@ VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection, case kProtectionKeyOnKeyLoss: { CriticalSectionScoped cs(_receiveCritSect); - if (enable) - { + if (enable) { _keyRequestMode = kKeyOnKeyLoss; - } - else if (_keyRequestMode == kKeyOnKeyLoss) - { - _keyRequestMode = kKeyOnError; // default mode - } - else - { + } else if (_keyRequestMode == kKeyOnKeyLoss) { + _keyRequestMode = kKeyOnError; // default mode + } else { return VCM_PARAMETER_ERROR; } break; @@ -648,19 +574,16 @@ VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection, { // Receive side CriticalSectionScoped cs(_receiveCritSect); - if (enable) - { + if (enable) { // Enable hybrid NACK/FEC. Always wait for retransmissions // and don't add extra delay when RTT is above // kLowRttNackMs. _receiver.SetNackMode(kNack, media_optimization::kLowRttNackMs, -1); - _receiver.SetDecodeWithErrors(false); - _receiver.SetDecodeWithErrors(false); - } - else - { + _receiver.SetDecodeErrorMode(kNoErrors); + _receiver.SetDecodeErrorMode(kNoErrors); + } else { _receiver.SetNackMode(kNoNack, -1, -1); } } @@ -693,44 +616,35 @@ VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection, // Add one raw video frame to the encoder, blocking. int32_t VideoCodingModuleImpl::AddVideoFrame(const I420VideoFrame& videoFrame, - const VideoContentMetrics* contentMetrics, - const CodecSpecificInfo* codecSpecificInfo) -{ + const VideoContentMetrics* contentMetrics, + const CodecSpecificInfo* codecSpecificInfo) { CriticalSectionScoped cs(_sendCritSect); - if (_encoder == NULL) - { + if (_encoder == NULL) { return VCM_UNINITIALIZED; } // TODO(holmer): Add support for dropping frames per stream. Currently we // only have one frame dropper for all streams. - if (_nextFrameTypes[0] == kFrameEmpty) - { + if (_nextFrameTypes[0] == kFrameEmpty) { return VCM_OK; } _mediaOpt.UpdateIncomingFrameRate(); - if (_mediaOpt.DropFrame()) - { + if (_mediaOpt.DropFrame()) { WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceVideoCoding, VCMId(_id), "Drop frame due to bitrate"); - } - else - { + } else { _mediaOpt.UpdateContentData(contentMetrics); int32_t ret = _encoder->Encode(videoFrame, codecSpecificInfo, _nextFrameTypes); - if (_encoderInputFile != NULL) - { - if (PrintI420VideoFrame(videoFrame, _encoderInputFile) < 0) - { + if (_encoderInputFile != NULL) { + if (PrintI420VideoFrame(videoFrame, _encoderInputFile) < 0) { return -1; } } - if (ret < 0) - { + if (ret < 0) { WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCoding, VCMId(_id), @@ -763,8 +677,7 @@ int32_t VideoCodingModuleImpl::IntraFrameRequest(int stream_index) { } int32_t -VideoCodingModuleImpl::EnableFrameDropper(bool enable) -{ +VideoCodingModuleImpl::EnableFrameDropper(bool enable) { CriticalSectionScoped cs(_sendCritSect); frame_dropper_enabled_ = enable; _mediaOpt.EnableFrameDropper(enable); @@ -773,26 +686,22 @@ VideoCodingModuleImpl::EnableFrameDropper(bool enable) int32_t -VideoCodingModuleImpl::SentFrameCount(VCMFrameCount &frameCount) const -{ +VideoCodingModuleImpl::SentFrameCount(VCMFrameCount &frameCount) const { CriticalSectionScoped cs(_sendCritSect); return _mediaOpt.SentFrameCount(frameCount); } // Initialize receiver, resets codec database etc int32_t -VideoCodingModuleImpl::InitializeReceiver() -{ +VideoCodingModuleImpl::InitializeReceiver() { CriticalSectionScoped cs(_receiveCritSect); int32_t ret = _receiver.Initialize(); - if (ret < 0) - { + if (ret < 0) { return ret; } ret = _dualReceiver.Initialize(); - if (ret < 0) - { + if (ret < 0) { return ret; } _codecDataBase.ResetReceiver(); @@ -815,8 +724,7 @@ VideoCodingModuleImpl::InitializeReceiver() // ready for rendering. int32_t VideoCodingModuleImpl::RegisterReceiveCallback( - VCMReceiveCallback* receiveCallback) -{ + VCMReceiveCallback* receiveCallback) { CriticalSectionScoped cs(_receiveCritSect); _decodedFrameCallback.SetUserReceiveCallback(receiveCallback); return VCM_OK; @@ -824,8 +732,7 @@ VideoCodingModuleImpl::RegisterReceiveCallback( int32_t VideoCodingModuleImpl::RegisterReceiveStatisticsCallback( - VCMReceiveStatisticsCallback* receiveStats) -{ + VCMReceiveStatisticsCallback* receiveStats) { CriticalSectionScoped cs(_receiveCritSect); _receiveStatsCallback = receiveStats; return VCM_OK; @@ -836,11 +743,9 @@ VideoCodingModuleImpl::RegisterReceiveStatisticsCallback( int32_t VideoCodingModuleImpl::RegisterExternalDecoder(VideoDecoder* externalDecoder, uint8_t payloadType, - bool internalRenderTiming) -{ + bool internalRenderTiming) { CriticalSectionScoped cs(_receiveCritSect); - if (externalDecoder == NULL) - { + if (externalDecoder == NULL) { // Make sure the VCM updates the decoder next time it decodes. _decoder = NULL; return _codecDataBase.DeregisterExternalDecoder(payloadType) ? 0 : -1; @@ -852,8 +757,7 @@ VideoCodingModuleImpl::RegisterExternalDecoder(VideoDecoder* externalDecoder, // Register a frame type request callback. int32_t VideoCodingModuleImpl::RegisterFrameTypeCallback( - VCMFrameTypeCallback* frameTypeCallback) -{ + VCMFrameTypeCallback* frameTypeCallback) { CriticalSectionScoped cs(_receiveCritSect); _frameTypeCallback = frameTypeCallback; return VCM_OK; @@ -861,8 +765,7 @@ VideoCodingModuleImpl::RegisterFrameTypeCallback( int32_t VideoCodingModuleImpl::RegisterFrameStorageCallback( - VCMFrameStorageCallback* frameStorageCallback) -{ + VCMFrameStorageCallback* frameStorageCallback) { CriticalSectionScoped cs(_receiveCritSect); _frameStorageCallback = frameStorageCallback; return VCM_OK; @@ -870,8 +773,7 @@ VideoCodingModuleImpl::RegisterFrameStorageCallback( int32_t VideoCodingModuleImpl::RegisterPacketRequestCallback( - VCMPacketRequestCallback* callback) -{ + VCMPacketRequestCallback* callback) { CriticalSectionScoped cs(_receiveCritSect); _packetRequestCallback = callback; return VCM_OK; @@ -887,17 +789,14 @@ int VideoCodingModuleImpl::RegisterRenderBufferSizeCallback( // Decode next frame, blocking. // Should be called as often as possible to get the most out of the decoder. int32_t -VideoCodingModuleImpl::Decode(uint16_t maxWaitTimeMs) -{ +VideoCodingModuleImpl::Decode(uint16_t maxWaitTimeMs) { int64_t nextRenderTimeMs; { CriticalSectionScoped cs(_receiveCritSect); - if (!_receiverInited) - { + if (!_receiverInited) { return VCM_UNINITIALIZED; } - if (!_codecDataBase.DecoderRegistered()) - { + if (!_codecDataBase.DecoderRegistered()) { return VCM_NO_CODEC_REGISTERED; } } @@ -912,34 +811,29 @@ VideoCodingModuleImpl::Decode(uint16_t maxWaitTimeMs) _codecDataBase.SupportsRenderScheduling(), &_dualReceiver); - if (dualReceiverEnabledNotReceiving && _dualReceiver.State() == kReceiving) - { + if (dualReceiverEnabledNotReceiving + && _dualReceiver.State() == kReceiving) { // Dual receiver is enabled (kNACK enabled), but was not receiving // before the call to FrameForDecoding(). After the call the state // changed to receiving, and therefore we must copy the primary decoder // state to the dual decoder to make it possible for the dual decoder to // start decoding retransmitted frames and recover. CriticalSectionScoped cs(_receiveCritSect); - if (_dualDecoder != NULL) - { + if (_dualDecoder != NULL) { _codecDataBase.ReleaseDecoder(_dualDecoder); } _dualDecoder = _codecDataBase.CreateDecoderCopy(); - if (_dualDecoder != NULL) - { + if (_dualDecoder != NULL) { _dualDecoder->RegisterDecodeCompleteCallback( &_dualDecodedFrameCallback); - } - else - { + } else { _dualReceiver.Reset(); } } - if (frame == NULL) + if (frame == NULL) { return VCM_FRAME_NOT_READY; - else - { + } else { CriticalSectionScoped cs(_receiveCritSect); // If this frame was too late, we should adjust the delay accordingly @@ -947,8 +841,7 @@ VideoCodingModuleImpl::Decode(uint16_t maxWaitTimeMs) clock_->TimeInMilliseconds()); #ifdef DEBUG_DECODER_BIT_STREAM - if (_bitStreamBeforeDecoder != NULL) - { + if (_bitStreamBeforeDecoder != NULL) { // Write bit stream to file for debugging purposes if (fwrite(frame->Buffer(), 1, frame->Length(), _bitStreamBeforeDecoder) != frame->Length()) { @@ -956,11 +849,9 @@ VideoCodingModuleImpl::Decode(uint16_t maxWaitTimeMs) } } #endif - if (_frameStorageCallback != NULL) - { + if (_frameStorageCallback != NULL) { int32_t ret = frame->Store(*_frameStorageCallback); - if (ret < 0) - { + if (ret < 0) { return ret; } } @@ -968,8 +859,7 @@ VideoCodingModuleImpl::Decode(uint16_t maxWaitTimeMs) const int32_t ret = Decode(*frame); _receiver.ReleaseFrame(frame); frame = NULL; - if (ret != VCM_OK) - { + if (ret != VCM_OK) { return ret; } } @@ -978,23 +868,19 @@ VideoCodingModuleImpl::Decode(uint16_t maxWaitTimeMs) int32_t VideoCodingModuleImpl::RequestSliceLossIndication( - const uint64_t pictureID) const -{ + const uint64_t pictureID) const { TRACE_EVENT1("webrtc", "RequestSLI", "picture_id", pictureID); - if (_frameTypeCallback != NULL) - { + if (_frameTypeCallback != NULL) { const int32_t ret = _frameTypeCallback->SliceLossIndicationRequest(pictureID); - if (ret < 0) - { + if (ret < 0) { WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCoding, VCMId(_id), "Failed to request key frame"); return ret; } - } else - { + } else { WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding, VCMId(_id), @@ -1005,14 +891,11 @@ VideoCodingModuleImpl::RequestSliceLossIndication( } int32_t -VideoCodingModuleImpl::RequestKeyFrame() -{ +VideoCodingModuleImpl::RequestKeyFrame() { TRACE_EVENT0("webrtc", "RequestKeyFrame"); - if (_frameTypeCallback != NULL) - { + if (_frameTypeCallback != NULL) { const int32_t ret = _frameTypeCallback->RequestKeyFrame(); - if (ret < 0) - { + if (ret < 0) { WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCoding, VCMId(_id), @@ -1020,9 +903,7 @@ VideoCodingModuleImpl::RequestKeyFrame() return ret; } _scheduleKeyRequest = false; - } - else - { + } else { WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding, VCMId(_id), @@ -1033,12 +914,10 @@ VideoCodingModuleImpl::RequestKeyFrame() } int32_t -VideoCodingModuleImpl::DecodeDualFrame(uint16_t maxWaitTimeMs) -{ +VideoCodingModuleImpl::DecodeDualFrame(uint16_t maxWaitTimeMs) { CriticalSectionScoped cs(_receiveCritSect); if (_dualReceiver.State() != kReceiving || - _dualReceiver.NackMode() != kNack) - { + _dualReceiver.NackMode() != kNack) { // The dual receiver is currently not receiving or // dual decoder mode is disabled. return VCM_OK; @@ -1048,12 +927,11 @@ VideoCodingModuleImpl::DecodeDualFrame(uint16_t maxWaitTimeMs) // The dual decoder's state is copied from the main decoder, which may // decode with errors. Make sure that the dual decoder does not introduce // error. - _dualReceiver.SetDecodeWithErrors(false); + _dualReceiver.SetDecodeErrorMode(kNoErrors); VCMEncodedFrame* dualFrame = _dualReceiver.FrameForDecoding( maxWaitTimeMs, dummyRenderTime); - if (dualFrame != NULL && _dualDecoder != NULL) - { + if (dualFrame != NULL && _dualDecoder != NULL) { WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceVideoCoding, VCMId(_id), @@ -1062,8 +940,7 @@ VideoCodingModuleImpl::DecodeDualFrame(uint16_t maxWaitTimeMs) // Decode dualFrame and try to catch up int32_t ret = _dualDecoder->Decode(*dualFrame, clock_->TimeInMilliseconds()); - if (ret != WEBRTC_VIDEO_CODEC_OK) - { + if (ret != WEBRTC_VIDEO_CODEC_OK) { WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding, VCMId(_id), @@ -1071,8 +948,7 @@ VideoCodingModuleImpl::DecodeDualFrame(uint16_t maxWaitTimeMs) _dualReceiver.ReleaseFrame(dualFrame); return VCM_CODEC_ERROR; } - if (_receiver.DualDecoderCaughtUp(dualFrame, _dualReceiver)) - { + if (_receiver.DualDecoderCaughtUp(dualFrame, _dualReceiver)) { // Copy the complete decoder state of the dual decoder // to the primary decoder. WEBRTC_TRACE(webrtc::kTraceStream, @@ -1092,37 +968,30 @@ VideoCodingModuleImpl::DecodeDualFrame(uint16_t maxWaitTimeMs) // Must be called from inside the receive side critical section. int32_t -VideoCodingModuleImpl::Decode(const VCMEncodedFrame& frame) -{ +VideoCodingModuleImpl::Decode(const VCMEncodedFrame& frame) { TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", frame.TimeStamp(), "Decode", "type", frame.FrameType()); // Change decoder if payload type has changed const bool renderTimingBefore = _codecDataBase.SupportsRenderScheduling(); _decoder = _codecDataBase.GetDecoder(frame.PayloadType(), &_decodedFrameCallback); - if (renderTimingBefore != _codecDataBase.SupportsRenderScheduling()) - { + if (renderTimingBefore != _codecDataBase.SupportsRenderScheduling()) { // Make sure we reset the decode time estimate since it will // be zero for codecs without render timing. _timing.ResetDecodeTime(); } - if (_decoder == NULL) - { + if (_decoder == NULL) { return VCM_NO_CODEC_REGISTERED; } // Decode a frame int32_t ret = _decoder->Decode(frame, clock_->TimeInMilliseconds()); // Check for failed decoding, run frame type request callback if needed. - if (ret < 0) - { - if (ret == VCM_ERROR_REQUEST_SLI) - { + if (ret < 0) { + if (ret == VCM_ERROR_REQUEST_SLI) { return RequestSliceLossIndication( _decodedFrameCallback.LastReceivedPictureID() + 1); - } - else - { + } else { WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCoding, VCMId(_id), @@ -1130,20 +999,15 @@ VideoCodingModuleImpl::Decode(const VCMEncodedFrame& frame) frame.TimeStamp()); ret = RequestKeyFrame(); } - } - else if (ret == VCM_REQUEST_SLI) - { + } else if (ret == VCM_REQUEST_SLI) { ret = RequestSliceLossIndication( _decodedFrameCallback.LastReceivedPictureID() + 1); } - if (!frame.Complete() || frame.MissingFrame()) - { - switch (_keyRequestMode) - { + if (!frame.Complete() || frame.MissingFrame()) { + switch (_keyRequestMode) { case kKeyOnKeyLoss: { - if (frame.FrameType() == kVideoFrameKey) - { + if (frame.FrameType() == kVideoFrameKey) { _scheduleKeyRequest = true; return VCM_OK; } @@ -1164,12 +1028,10 @@ VideoCodingModuleImpl::Decode(const VCMEncodedFrame& frame) int32_t VideoCodingModuleImpl::DecodeFromStorage( - const EncodedVideoData& frameFromStorage) -{ + const EncodedVideoData& frameFromStorage) { CriticalSectionScoped cs(_receiveCritSect); int32_t ret = _frameFromFile.ExtractFromStorage(frameFromStorage); - if (ret < 0) - { + if (ret < 0) { return ret; } return Decode(_frameFromFile); @@ -1177,22 +1039,18 @@ VideoCodingModuleImpl::DecodeFromStorage( // Reset the decoder state int32_t -VideoCodingModuleImpl::ResetDecoder() -{ +VideoCodingModuleImpl::ResetDecoder() { CriticalSectionScoped cs(_receiveCritSect); - if (_decoder != NULL) - { + if (_decoder != NULL) { _receiver.Initialize(); _timing.Reset(); _scheduleKeyRequest = false; _decoder->Reset(); } - if (_dualReceiver.State() != kPassive) - { + if (_dualReceiver.State() != kPassive) { _dualReceiver.Initialize(); } - if (_dualDecoder != NULL) - { + if (_dualDecoder != NULL) { _codecDataBase.ReleaseDecoder(_dualDecoder); _dualDecoder = NULL; } @@ -1203,11 +1061,9 @@ VideoCodingModuleImpl::ResetDecoder() int32_t VideoCodingModuleImpl::RegisterReceiveCodec(const VideoCodec* receiveCodec, int32_t numberOfCores, - bool requireKeyFrame) -{ + bool requireKeyFrame) { CriticalSectionScoped cs(_receiveCritSect); - if (receiveCodec == NULL) - { + if (receiveCodec == NULL) { return VCM_PARAMETER_ERROR; } if (!_codecDataBase.RegisterReceiveCodec(receiveCodec, numberOfCores, @@ -1219,11 +1075,9 @@ VideoCodingModuleImpl::RegisterReceiveCodec(const VideoCodec* receiveCodec, // Get current received codec int32_t -VideoCodingModuleImpl::ReceiveCodec(VideoCodec* currentReceiveCodec) const -{ +VideoCodingModuleImpl::ReceiveCodec(VideoCodec* currentReceiveCodec) const { CriticalSectionScoped cs(_receiveCritSect); - if (currentReceiveCodec == NULL) - { + if (currentReceiveCodec == NULL) { return VCM_PARAMETER_ERROR; } return _codecDataBase.ReceiveCodec(currentReceiveCodec) ? 0 : -1; @@ -1231,8 +1085,7 @@ VideoCodingModuleImpl::ReceiveCodec(VideoCodec* currentReceiveCodec) const // Get current received codec VideoCodecType -VideoCodingModuleImpl::ReceiveCodec() const -{ +VideoCodingModuleImpl::ReceiveCodec() const { CriticalSectionScoped cs(_receiveCritSect); return _codecDataBase.ReceiveCodec(); } @@ -1241,8 +1094,7 @@ VideoCodingModuleImpl::ReceiveCodec() const int32_t VideoCodingModuleImpl::IncomingPacket(const uint8_t* incomingPayload, uint32_t payloadLength, - const WebRtcRTPHeader& rtpInfo) -{ + const WebRtcRTPHeader& rtpInfo) { if (rtpInfo.frameType == kVideoFrameKey) { TRACE_EVENT1("webrtc", "VCM::PacketKeyFrame", "seqnum", rtpInfo.header.sequenceNumber); @@ -1255,8 +1107,7 @@ VideoCodingModuleImpl::IncomingPacket(const uint8_t* incomingPayload, } const VCMPacket packet(incomingPayload, payloadLength, rtpInfo); int32_t ret; - if (_dualReceiver.State() != kPassive) - { + if (_dualReceiver.State() != kPassive) { ret = _dualReceiver.InsertPacket(packet, rtpInfo.type.Video.width, rtpInfo.type.Video.height); @@ -1285,8 +1136,7 @@ VideoCodingModuleImpl::IncomingPacket(const uint8_t* incomingPayload, // to sync with audio. Not included in VideoCodingModule::Delay() // Defaults to 0 ms. int32_t -VideoCodingModuleImpl::SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs) -{ +VideoCodingModuleImpl::SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs) { _timing.set_min_playout_delay(minPlayoutDelayMs); return VCM_OK; } @@ -1294,40 +1144,34 @@ VideoCodingModuleImpl::SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs) // The estimated delay caused by rendering, defaults to // kDefaultRenderDelayMs = 10 ms int32_t -VideoCodingModuleImpl::SetRenderDelay(uint32_t timeMS) -{ +VideoCodingModuleImpl::SetRenderDelay(uint32_t timeMS) { _timing.set_render_delay(timeMS); return VCM_OK; } // Current video delay int32_t -VideoCodingModuleImpl::Delay() const -{ +VideoCodingModuleImpl::Delay() const { return _timing.TargetVideoDelay(); } // Nack list int32_t -VideoCodingModuleImpl::NackList(uint16_t* nackList, uint16_t& size) -{ +VideoCodingModuleImpl::NackList(uint16_t* nackList, uint16_t& size) { VCMNackStatus nackStatus = kNackOk; uint16_t nack_list_length = 0; // Collect sequence numbers from the default receiver // if in normal nack mode. Otherwise collect them from // the dual receiver if the dual receiver is receiving. - if (_receiver.NackMode() != kNoNack) - { + if (_receiver.NackMode() != kNoNack) { nackStatus = _receiver.NackList(nackList, size, &nack_list_length); } - if (nack_list_length == 0 && _dualReceiver.State() != kPassive) - { + if (nack_list_length == 0 && _dualReceiver.State() != kPassive) { nackStatus = _dualReceiver.NackList(nackList, size, &nack_list_length); } size = nack_list_length; - switch (nackStatus) - { + switch (nackStatus) { case kNackNeedMoreMemory: { WEBRTC_TRACE(webrtc::kTraceError, @@ -1352,8 +1196,7 @@ VideoCodingModuleImpl::NackList(uint16_t* nackList, uint16_t& size) } int32_t -VideoCodingModuleImpl::ReceivedFrameCount(VCMFrameCount& frameCount) const -{ +VideoCodingModuleImpl::ReceivedFrameCount(VCMFrameCount& frameCount) const { _receiver.ReceivedFrameCount(&frameCount); return VCM_OK; } @@ -1395,29 +1238,26 @@ int VideoCodingModuleImpl::SetSenderKeyFramePeriod(int periodMs) { int VideoCodingModuleImpl::SetReceiverRobustnessMode( ReceiverRobustness robustnessMode, - DecodeErrors errorMode) { + VCMDecodeErrorMode decode_error_mode) { CriticalSectionScoped cs(_receiveCritSect); switch (robustnessMode) { case kNone: _receiver.SetNackMode(kNoNack, -1, -1); _dualReceiver.SetNackMode(kNoNack, -1, -1); - if (errorMode == kNoDecodeErrors) { + if (decode_error_mode == kNoErrors) { _keyRequestMode = kKeyOnLoss; } else { _keyRequestMode = kKeyOnError; } break; case kHardNack: - if (errorMode == kAllowDecodeErrors) { - return VCM_PARAMETER_ERROR; - } - // Always wait for retransmissions. + // Always wait for retransmissions (except when decoding with errors). _receiver.SetNackMode(kNack, -1, -1); _dualReceiver.SetNackMode(kNoNack, -1, -1); _keyRequestMode = kKeyOnError; // TODO(hlundin): On long NACK list? break; case kSoftNack: - assert(false); // TODO(hlundin): Not completed. + assert(false); // TODO(hlundin): Not completed. return VCM_NOT_IMPLEMENTED; // Enable hybrid NACK/FEC. Always wait for retransmissions and don't add // extra delay when RTT is above kLowRttNackMs. @@ -1426,7 +1266,7 @@ int VideoCodingModuleImpl::SetReceiverRobustnessMode( _keyRequestMode = kKeyOnError; break; case kDualDecoder: - if (errorMode == kNoDecodeErrors) { + if (decode_error_mode == kNoErrors) { return VCM_PARAMETER_ERROR; } // Enable NACK but don't wait for retransmissions and don't add any extra @@ -1437,21 +1277,27 @@ int VideoCodingModuleImpl::SetReceiverRobustnessMode( _keyRequestMode = kKeyOnError; break; case kReferenceSelection: - assert(false); // TODO(hlundin): Not completed. + assert(false); // TODO(hlundin): Not completed. return VCM_NOT_IMPLEMENTED; - if (errorMode == kNoDecodeErrors) { + if (decode_error_mode == kNoErrors) { return VCM_PARAMETER_ERROR; } _receiver.SetNackMode(kNoNack, -1, -1); _dualReceiver.SetNackMode(kNoNack, -1, -1); break; } - _receiver.SetDecodeWithErrors(errorMode == kAllowDecodeErrors); + _receiver.SetDecodeErrorMode(decode_error_mode); // The dual decoder should never decode with errors. - _dualReceiver.SetDecodeWithErrors(false); + _dualReceiver.SetDecodeErrorMode(kNoErrors); return VCM_OK; } +void VideoCodingModuleImpl::SetDecodeErrorMode( + VCMDecodeErrorMode decode_error_mode) { + CriticalSectionScoped cs(_receiveCritSect); + _receiver.SetDecodeErrorMode(decode_error_mode); +} + void VideoCodingModuleImpl::SetNackSettings(size_t max_nack_list_size, int max_packet_age_to_nack, int max_incomplete_time_ms) { @@ -1477,7 +1323,7 @@ int VideoCodingModuleImpl::StartDebugRecording(const char* file_name_utf8) { return VCM_OK; } -int VideoCodingModuleImpl::StopDebugRecording(){ +int VideoCodingModuleImpl::StopDebugRecording() { CriticalSectionScoped cs(_sendCritSect); if (_encoderInputFile != NULL) { fclose(_encoderInputFile); diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.h b/webrtc/modules/video_coding/main/source/video_coding_impl.h index 64ccfe21a..13cb7b686 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.h +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.h @@ -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); diff --git a/webrtc/modules/video_coding/main/source/video_coding_robustness_unittest.cc b/webrtc/modules/video_coding/main/source/video_coding_robustness_unittest.cc index 4c92c5093..c8c10353e 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_robustness_unittest.cc +++ b/webrtc/modules/video_coding/main/source/video_coding_robustness_unittest.cc @@ -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);