Fix depacketizer state corruption if state is dropped in the middle of a frame

This commit is contained in:
Cameron Gutman 2018-09-04 14:33:18 -07:00
parent b9290449b4
commit 4a3521cfc6

View File

@ -59,6 +59,12 @@ static void cleanupFrameState(void) {
// Cleanup frame state and set that we're waiting for an IDR Frame // Cleanup frame state and set that we're waiting for an IDR Frame
static void dropFrameState(void) { static void dropFrameState(void) {
// This may only be called at frame boundaries
LC_ASSERT(!decodingFrame);
// We're dropping frame state now
dropStatePending = 0;
// We'll need an IDR frame now if we're in strict mode // We'll need an IDR frame now if we're in strict mode
if (strictIdrFrameWait) { if (strictIdrFrameWait) {
waitingForIdrFrame = 1; waitingForIdrFrame = 1;
@ -448,13 +454,6 @@ void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, unsigned long l
char flags; char flags;
unsigned int firstPacket; unsigned int firstPacket;
unsigned int streamPacketIndex; unsigned int streamPacketIndex;
// Before processing this packet at all, drop depacketizer
// state if the decoder asked for it.
if (dropStatePending) {
dropStatePending = 0;
dropFrameState();
}
// Mask the top 8 bits from the SPI // Mask the top 8 bits from the SPI
videoPacket->streamPacketIndex >>= 8; videoPacket->streamPacketIndex >>= 8;
@ -564,6 +563,17 @@ void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length, unsigned long l
return; return;
} }
// Carry out any pending state drops. We can't just do this
// arbitrarily in the middle of processing a frame because
// may cause the depacketizer state to become corrupted. For
// example, if we drop state after the first packet, the
// depacketizer will next try to process a non-SOF packet,
// and cause it to assert.
if (dropStatePending) {
dropFrameState();
return;
}
reassembleFrame(frameIndex); reassembleFrame(frameIndex);
startFrameNumber = nextFrameNumber; startFrameNumber = nextFrameNumber;