video_coding: Requesting a key frame after a JB flush
Review URL: http://webrtc-codereview.appspot.com/280006 git-svn-id: http://webrtc.googlecode.com/svn/trunk@994 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -298,7 +298,7 @@ VCMJitterBuffer::ReleaseFrameInternal(VCMFrameBuffer* frame)
|
||||
// Doing it here increases the degree of freedom for e.g. future
|
||||
// reconstructability of separate layers. Must be called under the
|
||||
// critical section _critSect.
|
||||
void
|
||||
VCMFrameBufferEnum
|
||||
VCMJitterBuffer::UpdateFrameState(VCMFrameBuffer* frame)
|
||||
{
|
||||
if (frame == NULL)
|
||||
@@ -306,7 +306,7 @@ VCMJitterBuffer::UpdateFrameState(VCMFrameBuffer* frame)
|
||||
WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCoding,
|
||||
VCMId(_vcmId, _receiverId), "JB(0x%x) FB(0x%x): "
|
||||
"UpdateFrameState NULL frame pointer", this, frame);
|
||||
return;
|
||||
return kNoError;
|
||||
}
|
||||
|
||||
int length = frame->Length();
|
||||
@@ -350,11 +350,11 @@ VCMJitterBuffer::UpdateFrameState(VCMFrameBuffer* frame)
|
||||
_dropCount, _numConsecutiveOldFrames);
|
||||
// Flush() if this happens consistently.
|
||||
_numConsecutiveOldFrames++;
|
||||
if (_numConsecutiveOldFrames > kMaxConsecutiveOldFrames)
|
||||
{
|
||||
FlushInternal();
|
||||
if (_numConsecutiveOldFrames > kMaxConsecutiveOldFrames) {
|
||||
FlushInternal();
|
||||
return kFlushIndicator;
|
||||
}
|
||||
return;
|
||||
return kNoError;
|
||||
}
|
||||
_numConsecutiveOldFrames = 0;
|
||||
frame->SetState(kStateComplete);
|
||||
@@ -405,6 +405,7 @@ VCMJitterBuffer::UpdateFrameState(VCMFrameBuffer* frame)
|
||||
{
|
||||
_frameEvent.Set();
|
||||
}
|
||||
return kNoError;
|
||||
}
|
||||
|
||||
// Get received key and delta frames
|
||||
@@ -451,6 +452,8 @@ VCMJitterBuffer::GetFrame(const VCMPacket& packet, VCMEncodedFrame*& frame)
|
||||
if (_numConsecutiveOldPackets > kMaxConsecutiveOldPackets)
|
||||
{
|
||||
FlushInternal();
|
||||
_critSect.Leave();
|
||||
return VCM_FLUSH_INDICATOR;
|
||||
}
|
||||
_critSect.Leave();
|
||||
return VCM_OLD_PACKET_ERROR;
|
||||
@@ -1697,7 +1700,9 @@ VCMJitterBuffer::InsertPacket(VCMEncodedFrame* buffer, const VCMPacket& packet)
|
||||
}
|
||||
case kCompleteSession:
|
||||
{
|
||||
UpdateFrameState(frame);
|
||||
// Only update return value for a JB flush indicator.
|
||||
if (UpdateFrameState(frame) == kFlushIndicator)
|
||||
ret = kFlushIndicator;
|
||||
// Signal that we have a received packet
|
||||
_packetEvent.Set();
|
||||
break;
|
||||
@@ -1719,8 +1724,7 @@ VCMJitterBuffer::InsertPacket(VCMEncodedFrame* buffer, const VCMPacket& packet)
|
||||
assert(!"JitterBuffer::InsertPacket: Undefined value");
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Must be called from within _critSect
|
||||
|
||||
@@ -145,7 +145,7 @@ private:
|
||||
bool RecycleFramesUntilKeyFrame();
|
||||
// Update frame state
|
||||
// (set as complete or reconstructable if conditions are met)
|
||||
void UpdateFrameState(VCMFrameBuffer* frameListItem);
|
||||
VCMFrameBufferEnum UpdateFrameState(VCMFrameBuffer* frameListItem);
|
||||
|
||||
// Help functions for getting a frame
|
||||
// Find oldest complete frame, used for getting next frame to decode
|
||||
|
||||
@@ -33,12 +33,13 @@ enum VCMJitterBufferEnum
|
||||
enum VCMFrameBufferEnum
|
||||
{
|
||||
kStateError = -4,
|
||||
kFlushIndicator = -3, // Indicator that a flush has occurred.
|
||||
kTimeStampError = -2,
|
||||
kSizeError = -1,
|
||||
kNoError = 0,
|
||||
kIncomplete = 1, // Frame incomplete
|
||||
kFirstPacket = 2,
|
||||
kCompleteSession = 3, // at least one layer in the frame complete
|
||||
kCompleteSession = 3, // at least one layer in the frame complete.
|
||||
kDecodableSession = 4, // Frame incomplete, but ready to be decoded
|
||||
kDuplicatePacket = 5 // We're receiving a duplicate packet.
|
||||
};
|
||||
|
||||
@@ -112,10 +112,11 @@ VCMReceiver::InsertPacket(const VCMPacket& packet,
|
||||
{
|
||||
// Only trace the primary receiver to make it possible
|
||||
// to parse and plot the trace file.
|
||||
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding, VCMId(_vcmId, _receiverId),
|
||||
"Packet seqNo %u of frame %u at %u",
|
||||
packet.seqNum, packet.timestamp,
|
||||
MaskWord64ToUWord32(VCMTickTime::MillisecondTimestamp()));
|
||||
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCoding,
|
||||
VCMId(_vcmId, _receiverId),
|
||||
"Packet seqNo %u of frame %u at %u",
|
||||
packet.seqNum, packet.timestamp,
|
||||
MaskWord64ToUWord32(VCMTickTime::MillisecondTimestamp()));
|
||||
}
|
||||
|
||||
const WebRtc_Word64 nowMs = VCMTickTime::MillisecondTimestamp();
|
||||
@@ -128,7 +129,7 @@ VCMReceiver::InsertPacket(const VCMPacket& packet,
|
||||
// the incoming video stream and reset the JB and the timing.
|
||||
_jitterBuffer.Flush();
|
||||
_timing.Reset();
|
||||
return VCM_OK;
|
||||
return VCM_FLUSH_INDICATOR;
|
||||
}
|
||||
else if (renderTimeMs < nowMs - kMaxVideoDelayMs)
|
||||
{
|
||||
@@ -137,7 +138,7 @@ VCMReceiver::InsertPacket(const VCMPacket& packet,
|
||||
"Flushing jitter buffer and resetting timing.", kMaxVideoDelayMs);
|
||||
_jitterBuffer.Flush();
|
||||
_timing.Reset();
|
||||
return VCM_OK;
|
||||
return VCM_FLUSH_INDICATOR;
|
||||
}
|
||||
else if (_timing.TargetVideoDelay() > kMaxVideoDelayMs)
|
||||
{
|
||||
@@ -146,7 +147,7 @@ VCMReceiver::InsertPacket(const VCMPacket& packet,
|
||||
kMaxVideoDelayMs);
|
||||
_jitterBuffer.Flush();
|
||||
_timing.Reset();
|
||||
return VCM_OK;
|
||||
return VCM_FLUSH_INDICATOR;
|
||||
}
|
||||
|
||||
// First packet received belonging to this frame.
|
||||
@@ -171,16 +172,18 @@ VCMReceiver::InsertPacket(const VCMPacket& packet,
|
||||
}
|
||||
}
|
||||
|
||||
// Insert packet into jitter buffer
|
||||
// Insert packet into the jitter buffer
|
||||
// both media and empty packets
|
||||
const VCMFrameBufferEnum ret = _jitterBuffer.InsertPacket(buffer, packet);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCoding, VCMId(_vcmId, _receiverId),
|
||||
const VCMFrameBufferEnum
|
||||
ret = _jitterBuffer.InsertPacket(buffer, packet);
|
||||
if (ret == kFlushIndicator) {
|
||||
return VCM_FLUSH_INDICATOR;
|
||||
} else if (ret < 0) {
|
||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCoding,
|
||||
VCMId(_vcmId, _receiverId),
|
||||
"Error inserting packet seqNo=%u, timeStamp=%u",
|
||||
packet.seqNum, packet.timestamp);
|
||||
return VCM_JITTER_BUFFER_ERROR;
|
||||
return VCM_JITTER_BUFFER_ERROR;
|
||||
}
|
||||
}
|
||||
return VCM_OK;
|
||||
|
||||
@@ -1409,16 +1409,20 @@ VideoCodingModuleImpl::IncomingPacket(const WebRtc_UWord8* incomingPayload,
|
||||
ret = _dualReceiver.InsertPacket(packet,
|
||||
rtpInfo.type.Video.width,
|
||||
rtpInfo.type.Video.height);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
if (ret == VCM_FLUSH_INDICATOR) {
|
||||
RequestKeyFrame();
|
||||
ResetDecoder();
|
||||
} else if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = _receiver.InsertPacket(packet, rtpInfo.type.Video.width,
|
||||
rtpInfo.type.Video.height);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
if (ret == VCM_FLUSH_INDICATOR) {
|
||||
RequestKeyFrame();
|
||||
ResetDecoder();
|
||||
} else if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
return VCM_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user