VCM/JB: FrameForDecoding->IncompleteFrameForDecoding
- Update complete frame for decoding - Remove FrameForDecodingNack This CL should only be committed after issue http://webrtc-codereview.appspot.com/1313007/ Review URL: https://webrtc-codereview.appspot.com/1316007 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3901 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -438,7 +438,6 @@ VCMEncodedFrame* VCMJitterBuffer::GetCompleteFrameForDecoding(
|
||||
if (!running_) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CleanUpOldOrEmptyFrames();
|
||||
|
||||
if (last_decoded_state_.in_initial_state()) {
|
||||
@ -482,16 +481,17 @@ VCMEncodedFrame* VCMJitterBuffer::GetCompleteFrameForDecoding(
|
||||
frame_event_->Reset();
|
||||
}
|
||||
|
||||
if (it == frame_list_.end()) {
|
||||
if (!decode_with_errors_ && it == frame_list_.end()) {
|
||||
// Even after signaling we're still missing a complete continuous frame.
|
||||
// Look for a complete key frame.
|
||||
// Look for a complete key frame if we're not decoding with errors.
|
||||
it = find_if(frame_list_.begin(), frame_list_.end(),
|
||||
CompleteKeyFrameCriteria());
|
||||
}
|
||||
|
||||
if (it == frame_list_.end()) {
|
||||
crit_sect_->Leave();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
VCMFrameBuffer* oldest_frame = *it;
|
||||
|
||||
@ -530,15 +530,15 @@ VCMEncodedFrame* VCMJitterBuffer::GetCompleteFrameForDecoding(
|
||||
return oldest_frame;
|
||||
}
|
||||
|
||||
VCMEncodedFrame* VCMJitterBuffer::GetFrameForDecoding() {
|
||||
TRACE_EVENT0("webrtc", "JB::GetFrameForDecoding");
|
||||
VCMEncodedFrame* VCMJitterBuffer::MaybeGetIncompleteFrameForDecoding() {
|
||||
TRACE_EVENT0("webrtc", "JB::MaybeGetIncompleteFrameForDecoding");
|
||||
CriticalSectionScoped cs(crit_sect_);
|
||||
if (!running_) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (WaitForRetransmissions()) {
|
||||
return GetFrameForDecodingNACK();
|
||||
if (!decode_with_errors_) {
|
||||
// No point to continue, as we are not decoding with errors.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CleanUpOldOrEmptyFrames();
|
||||
@ -548,15 +548,13 @@ VCMEncodedFrame* VCMJitterBuffer::GetFrameForDecoding() {
|
||||
}
|
||||
|
||||
VCMFrameBuffer* oldest_frame = frame_list_.front();
|
||||
if (frame_list_.size() <= 1 &&
|
||||
oldest_frame->GetState() != kStateComplete) {
|
||||
// If we have only one frame in the buffer, release it only if it is complete.
|
||||
if (frame_list_.size() <= 1 && oldest_frame->GetState() != kStateComplete) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Incomplete frame pulled out from jitter buffer,
|
||||
// update the jitter estimate with what we currently know.
|
||||
// This frame shouldn't have been retransmitted, but if we recently
|
||||
// turned off NACK this might still happen.
|
||||
const bool retransmitted = (oldest_frame->GetNackCount() > 0);
|
||||
if (retransmitted) {
|
||||
jitter_estimate_.FrameNacked();
|
||||
@ -998,57 +996,6 @@ int64_t VCMJitterBuffer::LastDecodedTimestamp() const {
|
||||
return last_decoded_state_.time_stamp();
|
||||
}
|
||||
|
||||
VCMEncodedFrame* VCMJitterBuffer::GetFrameForDecodingNACK() {
|
||||
TRACE_EVENT0("webrtc", "JB::GetFrameForDecodingNACK");
|
||||
CleanUpOldOrEmptyFrames();
|
||||
// First look for a complete continuous frame.
|
||||
// When waiting for nack, wait for a key frame, if a continuous frame cannot
|
||||
// be determined (i.e. initial decoding state).
|
||||
if (last_decoded_state_.in_initial_state()) {
|
||||
waiting_for_key_frame_ = true;
|
||||
}
|
||||
FrameList::iterator it = FindOldestCompleteContinuousFrame();
|
||||
if (it == frame_list_.end()) {
|
||||
// If we didn't find one we're good with a complete key frame.
|
||||
it = find_if(frame_list_.begin(), frame_list_.end(),
|
||||
CompleteKeyFrameCriteria());
|
||||
if (it == frame_list_.end()) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
VCMFrameBuffer* oldest_frame = *it;
|
||||
// Update jitter estimate
|
||||
const bool retransmitted = (oldest_frame->GetNackCount() > 0);
|
||||
if (retransmitted) {
|
||||
jitter_estimate_.FrameNacked();
|
||||
} else if (oldest_frame->Length() > 0) {
|
||||
// Ignore retransmitted and empty frames.
|
||||
UpdateJitterEstimate(*oldest_frame, false);
|
||||
}
|
||||
it = frame_list_.erase(it);
|
||||
if (frame_list_.empty()) {
|
||||
TRACE_EVENT_INSTANT1("webrtc", "JB::FrameListEmptied",
|
||||
"type", "GetFrameForDecodingNACK");
|
||||
}
|
||||
|
||||
// Look for previous frame loss.
|
||||
VerifyAndSetPreviousFrameLost(oldest_frame);
|
||||
|
||||
// The state must be changed to decoding before cleaning up zero sized
|
||||
// frames to avoid empty frames being cleaned up and then given to the
|
||||
// decoder.
|
||||
oldest_frame->SetState(kStateDecoding);
|
||||
|
||||
if (oldest_frame->FrameType() == kVideoFrameKey) {
|
||||
waiting_for_key_frame_ = false;
|
||||
}
|
||||
|
||||
// We have a frame - update decoded state with frame info.
|
||||
last_decoded_state_.SetState(oldest_frame);
|
||||
DropPacketsFromNackList(last_decoded_state_.sequence_num());
|
||||
return oldest_frame;
|
||||
}
|
||||
|
||||
// Set the frame state to free and remove it from the sorted
|
||||
// frame list. Must be called from inside the critical section crit_sect_.
|
||||
void VCMJitterBuffer::ReleaseFrameIfNotDecoding(VCMFrameBuffer* frame) {
|
||||
|
@ -104,13 +104,16 @@ class VCMJitterBuffer {
|
||||
// or more packets.
|
||||
bool CompleteSequenceWithNextFrame();
|
||||
|
||||
// TODO(mikhal/stefan): Merge all GetFrameForDecoding into one.
|
||||
// Wait |max_wait_time_ms| for a complete frame to arrive. After timeout NULL
|
||||
// is returned.
|
||||
// Returns a complete frame ready for decoding. Allows max_wait_time_ms to
|
||||
// wait for such a frame, if one is unavailable.
|
||||
// Always starts with a key frame.
|
||||
VCMEncodedFrame* GetCompleteFrameForDecoding(uint32_t max_wait_time_ms);
|
||||
|
||||
// Get a frame for decoding (even an incomplete) without delay.
|
||||
VCMEncodedFrame* GetFrameForDecoding();
|
||||
// Get next frame for decoding without delay. If decoding with errors is not
|
||||
// enabled, will return NULL. Actual returned frame will be the next one in
|
||||
// the list, either complete or not.
|
||||
// TODO(mikhal): Consider only allowing decodable/complete.
|
||||
VCMEncodedFrame* MaybeGetIncompleteFrameForDecoding();
|
||||
|
||||
// Releases a frame returned from the jitter buffer, should be called when
|
||||
// done with decoding.
|
||||
@ -189,11 +192,6 @@ class VCMJitterBuffer {
|
||||
// Drops all packets in the NACK list up until |last_decoded_sequence_number|.
|
||||
void DropPacketsFromNackList(uint16_t last_decoded_sequence_number);
|
||||
|
||||
// In NACK-only mode this function doesn't return or release non-complete
|
||||
// frames unless we have a complete key frame. In hybrid mode, we may release
|
||||
// "decodable", incomplete frames.
|
||||
VCMEncodedFrame* GetFrameForDecodingNACK();
|
||||
|
||||
void ReleaseFrameIfNotDecoding(VCMFrameBuffer* frame);
|
||||
|
||||
// Gets an empty frame, creating a new frame if necessary (i.e. increases
|
||||
|
@ -241,8 +241,9 @@ class TestRunningJitterBuffer : public ::testing::Test {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DecodeFrame() {
|
||||
VCMEncodedFrame* frame = jitter_buffer_->GetFrameForDecoding();
|
||||
bool DecodeIncompleteFrame() {
|
||||
VCMEncodedFrame* frame =
|
||||
jitter_buffer_->MaybeGetIncompleteFrameForDecoding();
|
||||
bool ret = (frame != NULL);
|
||||
jitter_buffer_->ReleaseFrame(frame);
|
||||
return ret;
|
||||
@ -416,7 +417,7 @@ TEST_F(TestJitterBufferNack, NackTooOldPackets) {
|
||||
EXPECT_GE(InsertFrame(kVideoFrameDelta), kNoError);
|
||||
// Waiting for a key frame.
|
||||
EXPECT_FALSE(DecodeCompleteFrame());
|
||||
EXPECT_FALSE(DecodeFrame());
|
||||
EXPECT_FALSE(DecodeIncompleteFrame());
|
||||
|
||||
// The next complete continuous frame isn't a key frame, but we're waiting
|
||||
// for one.
|
||||
@ -466,7 +467,7 @@ TEST_F(TestJitterBufferNack, NackListFull) {
|
||||
// The next complete continuous frame isn't a key frame, but we're waiting
|
||||
// for one.
|
||||
EXPECT_FALSE(DecodeCompleteFrame());
|
||||
EXPECT_FALSE(DecodeFrame());
|
||||
EXPECT_FALSE(DecodeIncompleteFrame());
|
||||
EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError);
|
||||
// Skipping ahead to the key frame.
|
||||
EXPECT_TRUE(DecodeCompleteFrame());
|
||||
@ -521,9 +522,10 @@ TEST_F(TestJitterBufferNack, UseNackToRecoverFirstKeyFrame) {
|
||||
|
||||
TEST_F(TestJitterBufferNack, NormalOperation) {
|
||||
EXPECT_EQ(kNack, jitter_buffer_->nack_mode());
|
||||
jitter_buffer_->DecodeWithErrors(true);
|
||||
|
||||
EXPECT_GE(InsertFrame(kVideoFrameKey), kNoError);
|
||||
EXPECT_TRUE(DecodeFrame());
|
||||
EXPECT_TRUE(DecodeIncompleteFrame());
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// | 1 | 2 | .. | 8 | 9 | x | 11 | 12 | .. | 19 | x | 21 | .. | 100 |
|
||||
@ -544,7 +546,7 @@ TEST_F(TestJitterBufferNack, NormalOperation) {
|
||||
EXPECT_EQ(kIncomplete, InsertPacketAndPop(0));
|
||||
EXPECT_EQ(0, stream_generator->PacketsRemaining());
|
||||
EXPECT_FALSE(DecodeCompleteFrame());
|
||||
EXPECT_FALSE(DecodeFrame());
|
||||
EXPECT_FALSE(DecodeIncompleteFrame());
|
||||
uint16_t nack_list_size = 0;
|
||||
bool request_key_frame = false;
|
||||
uint16_t* list = jitter_buffer_->GetNackList(&nack_list_size,
|
||||
|
@ -254,11 +254,8 @@ VCMEncodedFrame* VCMReceiver::FrameForDecoding(
|
||||
!jitter_buffer_.CompleteSequenceWithNextFrame()) {
|
||||
// Jitter buffer state might get corrupt with this frame.
|
||||
dual_receiver->CopyJitterBufferStateFromReceiver(*this);
|
||||
frame = jitter_buffer_.GetFrameForDecoding();
|
||||
assert(frame);
|
||||
} else {
|
||||
frame = jitter_buffer_.GetFrameForDecoding();
|
||||
}
|
||||
frame = jitter_buffer_.MaybeGetIncompleteFrameForDecoding();
|
||||
}
|
||||
if (frame == NULL) {
|
||||
// Wait for a complete frame.
|
||||
@ -282,7 +279,7 @@ VCMEncodedFrame* VCMReceiver::FrameForDecoding(
|
||||
dual_receiver->CopyJitterBufferStateFromReceiver(*this);
|
||||
}
|
||||
|
||||
frame = jitter_buffer_.GetFrameForDecoding();
|
||||
frame = jitter_buffer_.MaybeGetIncompleteFrameForDecoding();
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
@ -320,7 +317,7 @@ VCMEncodedFrame* VCMReceiver::FrameForRendering(uint16_t max_wait_time_ms,
|
||||
dual_receiver->CopyJitterBufferStateFromReceiver(*this);
|
||||
}
|
||||
|
||||
frame = jitter_buffer_.GetFrameForDecoding();
|
||||
frame = jitter_buffer_.MaybeGetIncompleteFrameForDecoding();
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
@ -412,6 +409,16 @@ VCMReceiverState VCMReceiver::State() const {
|
||||
return state_;
|
||||
}
|
||||
|
||||
void VCMReceiver::SetDecodeWithErrors(bool enable){
|
||||
CriticalSectionScoped cs(crit_sect_);
|
||||
jitter_buffer_.DecodeWithErrors(enable);
|
||||
}
|
||||
|
||||
bool VCMReceiver::DecodeWithErrors() const {
|
||||
CriticalSectionScoped cs(crit_sect_);
|
||||
return jitter_buffer_.decode_with_errors();
|
||||
}
|
||||
|
||||
int VCMReceiver::SetMinReceiverDelay(int desired_delay_ms) {
|
||||
CriticalSectionScoped cs(crit_sect_);
|
||||
if (desired_delay_ms < 0 || desired_delay_ms > kMaxReceiverDelayMs) {
|
||||
|
@ -76,6 +76,10 @@ class VCMReceiver {
|
||||
// Receiver video delay.
|
||||
int SetMinReceiverDelay(int desired_delay_ms);
|
||||
|
||||
// Decoding with errors.
|
||||
void SetDecodeWithErrors(bool enable);
|
||||
bool DecodeWithErrors() const;
|
||||
|
||||
private:
|
||||
VCMEncodedFrame* FrameForDecoding(uint16_t max_wait_time_ms,
|
||||
int64_t nextrender_time_ms,
|
||||
|
@ -535,10 +535,17 @@ VideoCodingModuleImpl::RegisterProtectionCallback(
|
||||
}
|
||||
|
||||
// Enable or disable a video protection method.
|
||||
// Note: This API should be deprecated, as it does not offer a distinction
|
||||
// between the protection method and decoding with or without errors. If such a
|
||||
// behavior is desired, use the following API: SetReceiverRobustnessMode.
|
||||
int32_t
|
||||
VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection,
|
||||
bool enable)
|
||||
{
|
||||
// By default, do not decode with errors.
|
||||
_receiver.SetDecodeWithErrors(false);
|
||||
// The dual decoder should always be error free.
|
||||
_dualReceiver.SetDecodeWithErrors(false);
|
||||
switch (videoProtection)
|
||||
{
|
||||
|
||||
@ -583,6 +590,7 @@ VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection,
|
||||
// Enable NACK and always wait for retransmissions and
|
||||
// compensate with extra delay.
|
||||
_dualReceiver.SetNackMode(kNack, -1, -1);
|
||||
_receiver.SetDecodeWithErrors(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -597,6 +605,7 @@ VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection,
|
||||
if (enable)
|
||||
{
|
||||
_keyRequestMode = kKeyOnLoss;
|
||||
_receiver.SetDecodeWithErrors(true);
|
||||
}
|
||||
else if (_keyRequestMode == kKeyOnLoss)
|
||||
{
|
||||
@ -640,6 +649,8 @@ VideoCodingModuleImpl::SetVideoProtection(VCMVideoProtection videoProtection,
|
||||
_receiver.SetNackMode(kNack,
|
||||
media_optimization::kLowRttNackMs,
|
||||
-1);
|
||||
_receiver.SetDecodeWithErrors(false);
|
||||
_receiver.SetDecodeWithErrors(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1021,6 +1032,10 @@ VideoCodingModuleImpl::DecodeDualFrame(uint16_t maxWaitTimeMs)
|
||||
}
|
||||
int64_t dummyRenderTime;
|
||||
int32_t decodeCount = 0;
|
||||
// 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);
|
||||
VCMEncodedFrame* dualFrame = _dualReceiver.FrameForDecoding(
|
||||
maxWaitTimeMs,
|
||||
dummyRenderTime);
|
||||
@ -1417,6 +1432,9 @@ int VideoCodingModuleImpl::SetReceiverRobustnessMode(
|
||||
_dualReceiver.SetNackMode(kNoNack, -1, -1);
|
||||
break;
|
||||
}
|
||||
_receiver.SetDecodeWithErrors(errorMode == kAllowDecodeErrors);
|
||||
// The dual decoder should never decode with errors.
|
||||
_dualReceiver.SetDecodeWithErrors(false);
|
||||
return VCM_OK;
|
||||
}
|
||||
|
||||
|
@ -329,73 +329,4 @@ TEST_F(VCMRobustnessTest, TestModeNoneWithErrors) {
|
||||
InsertPacket(9000, 11, false, true, kVideoFrameDelta);
|
||||
EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 9000 complete.
|
||||
}
|
||||
|
||||
TEST_F(VCMRobustnessTest, TestModeNoneWithoutErrors) {
|
||||
Sequence s1;
|
||||
EXPECT_CALL(decoder_, InitDecode(_, _)).Times(1);
|
||||
EXPECT_CALL(decoder_, Release()).Times(1);
|
||||
EXPECT_CALL(request_callback_, ResendPackets(_, 1))
|
||||
.With(Args<0, 1>(ElementsAre(4)))
|
||||
.Times(0);
|
||||
|
||||
EXPECT_CALL(decoder_, Copy())
|
||||
.Times(0);
|
||||
EXPECT_CALL(decoderCopy_, Copy())
|
||||
.Times(0);
|
||||
|
||||
// Decode operations
|
||||
EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 0),
|
||||
Field(&EncodedImage::_completeFrame,
|
||||
true)),
|
||||
false, _, _, _))
|
||||
.Times(1)
|
||||
.InSequence(s1);
|
||||
EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 3000),
|
||||
Field(&EncodedImage::_completeFrame,
|
||||
false)),
|
||||
false, _, _, _))
|
||||
.Times(1)
|
||||
.InSequence(s1);
|
||||
EXPECT_CALL(decoder_, Decode(AllOf(Field(&EncodedImage::_timeStamp, 6000),
|
||||
Field(&EncodedImage::_completeFrame,
|
||||
true)),
|
||||
false, _, _, _))
|
||||
.Times(1)
|
||||
.InSequence(s1);
|
||||
EXPECT_CALL(frame_type_callback_, RequestKeyFrame())
|
||||
.Times(1);
|
||||
|
||||
ASSERT_EQ(VCM_OK, vcm_->SetReceiverRobustnessMode(
|
||||
VideoCodingModule::kNone,
|
||||
VideoCodingModule::kNoDecodeErrors));
|
||||
|
||||
InsertPacket(0, 0, true, false, kVideoFrameKey);
|
||||
InsertPacket(0, 1, false, false, kVideoFrameKey);
|
||||
InsertPacket(0, 2, false, true, kVideoFrameKey);
|
||||
EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 0.
|
||||
EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list.
|
||||
|
||||
clock_->AdvanceTimeMilliseconds(33);
|
||||
InsertPacket(3000, 3, true, false, kVideoFrameDelta);
|
||||
// Packet 4 missing
|
||||
InsertPacket(3000, 5, false, true, kVideoFrameDelta);
|
||||
EXPECT_EQ(VCM_FRAME_NOT_READY, vcm_->Decode(0));
|
||||
EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list.
|
||||
|
||||
clock_->AdvanceTimeMilliseconds(33);
|
||||
InsertPacket(6000, 6, true, false, kVideoFrameDelta);
|
||||
InsertPacket(6000, 7, false, false, kVideoFrameDelta);
|
||||
InsertPacket(6000, 8, false, true, kVideoFrameDelta);
|
||||
EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 3000 incomplete.
|
||||
// Schedule key frame request.
|
||||
EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list.
|
||||
|
||||
clock_->AdvanceTimeMilliseconds(10);
|
||||
EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 6000 complete.
|
||||
EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list.
|
||||
|
||||
// Wait for the key request timer to set.
|
||||
clock_->AdvanceTimeMilliseconds(500);
|
||||
EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect key frame request.
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
@ -136,11 +136,14 @@ int JitterBufferTest(CmdArgs& args)
|
||||
TEST(0 == jb.GetFrame(packet));
|
||||
TEST(-1 == jb.NextTimestamp(10, &incomingFrameType, &renderTimeMs));
|
||||
TEST(0 == jb.GetCompleteFrameForDecoding(10));
|
||||
TEST(0 == jb.GetFrameForDecoding());
|
||||
TEST(0 == jb.MaybeGetIncompleteFrameForDecoding());
|
||||
|
||||
// Start
|
||||
jb.Start();
|
||||
|
||||
// Allow decoding with errors.
|
||||
jb.DecodeWithErrors(true);
|
||||
|
||||
// Get frame to use for this timestamp
|
||||
VCMEncodedFrame* frameIn = jb.GetFrame(packet);
|
||||
TEST(frameIn != 0);
|
||||
@ -808,7 +811,7 @@ int JitterBufferTest(CmdArgs& args)
|
||||
TEST(kIncomplete == jb.InsertPacket(frameIn, packet));
|
||||
|
||||
// Get the frame
|
||||
frameOut = jb.GetFrameForDecoding();
|
||||
frameOut = jb.MaybeGetIncompleteFrameForDecoding();
|
||||
|
||||
// One of the packets has been discarded by the jitter buffer.
|
||||
// Last frame can't be extracted yet.
|
||||
@ -1665,7 +1668,7 @@ int JitterBufferTest(CmdArgs& args)
|
||||
packet.seqNum = seqNum;
|
||||
packet.timestamp = timeStamp;
|
||||
packet.frameType = kFrameEmpty;
|
||||
VCMEncodedFrame* testFrame = jb.GetFrameForDecoding();
|
||||
VCMEncodedFrame* testFrame = jb.MaybeGetIncompleteFrameForDecoding();
|
||||
// timestamp should bever be the last TS inserted
|
||||
if (testFrame != NULL)
|
||||
{
|
||||
@ -1744,7 +1747,7 @@ int JitterBufferTest(CmdArgs& args)
|
||||
// Get packet notification
|
||||
TEST(timeStamp == jb.NextTimestamp(10, &incomingFrameType,
|
||||
&renderTimeMs));
|
||||
frameOut = jb.GetFrameForDecoding();
|
||||
frameOut = jb.MaybeGetIncompleteFrameForDecoding();
|
||||
|
||||
// We can decode everything from a NALU until a packet has been lost.
|
||||
// Thus we can decode the first packet of the first NALU and the second NALU
|
||||
@ -1810,7 +1813,7 @@ int JitterBufferTest(CmdArgs& args)
|
||||
// This packet should not be decoded because it is an incomplete NAL if it
|
||||
// is the last
|
||||
|
||||
frameOut = jb.GetFrameForDecoding();
|
||||
frameOut = jb.MaybeGetIncompleteFrameForDecoding();
|
||||
// Only last NALU is complete
|
||||
TEST(CheckOutFrame(frameOut, insertedLength, false) == 0);
|
||||
jb.ReleaseFrame(frameOut);
|
||||
@ -1834,7 +1837,7 @@ int JitterBufferTest(CmdArgs& args)
|
||||
|
||||
// Will be sent to the decoder, as a packet belonging to a subsequent frame
|
||||
// has arrived.
|
||||
frameOut = jb.GetFrameForDecoding();
|
||||
frameOut = jb.MaybeGetIncompleteFrameForDecoding();
|
||||
|
||||
|
||||
// Test that a frame can include an empty packet.
|
||||
@ -1880,7 +1883,7 @@ int JitterBufferTest(CmdArgs& args)
|
||||
TEST(frameIn = jb.GetFrame(packet));
|
||||
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
||||
|
||||
frameOut = jb.GetFrameForDecoding();
|
||||
frameOut = jb.MaybeGetIncompleteFrameForDecoding();
|
||||
TEST(frameOut == NULL);
|
||||
|
||||
packet.seqNum += 2;
|
||||
@ -1889,7 +1892,7 @@ int JitterBufferTest(CmdArgs& args)
|
||||
TEST(frameIn = jb.GetFrame(packet));
|
||||
TEST(kFirstPacket == jb.InsertPacket(frameIn, packet));
|
||||
|
||||
frameOut = jb.GetFrameForDecoding();
|
||||
frameOut = jb.MaybeGetIncompleteFrameForDecoding();
|
||||
|
||||
TEST(frameOut != NULL);
|
||||
TEST(CheckOutFrame(frameOut, packet.sizeBytes, false) == 0);
|
||||
|
Reference in New Issue
Block a user