Fix mishandling of IDR frames with a VUI or AUD NAL
This commit is contained in:
parent
e453a4d548
commit
50603ac16e
1 changed files with 25 additions and 18 deletions
|
|
@ -138,7 +138,7 @@ void destroyVideoDepacketizer(void) {
|
||||||
cleanupFrameState();
|
cleanupFrameState();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool getAnnexBStartSequence(PBUFFER_DESC current, PBUFFER_DESC candidate) {
|
static bool getAnnexBStartSequence(PBUFFER_DESC current, PBUFFER_DESC startSeq) {
|
||||||
if (current->length < 3) {
|
if (current->length < 3) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -148,17 +148,21 @@ static bool getAnnexBStartSequence(PBUFFER_DESC current, PBUFFER_DESC candidate)
|
||||||
if (current->data[current->offset + 2] == 0) {
|
if (current->data[current->offset + 2] == 0) {
|
||||||
if (current->length >= 4 && current->data[current->offset + 3] == 1) {
|
if (current->length >= 4 && current->data[current->offset + 3] == 1) {
|
||||||
// Frame start
|
// Frame start
|
||||||
candidate->data = current->data;
|
if (startSeq != NULL) {
|
||||||
candidate->offset = current->offset;
|
startSeq->data = current->data;
|
||||||
candidate->length = 4;
|
startSeq->offset = current->offset;
|
||||||
|
startSeq->length = 4;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (current->data[current->offset + 2] == 1) {
|
else if (current->data[current->offset + 2] == 1) {
|
||||||
// NAL start
|
// NAL start
|
||||||
candidate->data = current->data;
|
if (startSeq != NULL) {
|
||||||
candidate->offset = current->offset;
|
startSeq->data = current->data;
|
||||||
candidate->length = 3;
|
startSeq->offset = current->offset;
|
||||||
|
startSeq->length = 3;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -239,12 +243,18 @@ void LiCompleteVideoFrame(VIDEO_FRAME_HANDLE handle, int drStatus) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isSeqReferenceFrameStart(PBUFFER_DESC startSeq) {
|
static bool isSeqReferenceFrameStart(PBUFFER_DESC buffer) {
|
||||||
|
BUFFER_DESC startSeq;
|
||||||
|
|
||||||
|
if (!getAnnexBStartSequence(buffer, &startSeq)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H264) {
|
if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H264) {
|
||||||
return H264_NAL_TYPE(startSeq->data[startSeq->offset + startSeq->length]) == 5;
|
return H264_NAL_TYPE(startSeq.data[startSeq.offset + startSeq.length]) == 5;
|
||||||
}
|
}
|
||||||
else if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H265) {
|
else if (NegotiatedVideoFormat & VIDEO_FORMAT_MASK_H265) {
|
||||||
switch (HEVC_NAL_TYPE(startSeq->data[startSeq->offset + startSeq->length])) {
|
switch (HEVC_NAL_TYPE(startSeq.data[startSeq.offset + startSeq.length])) {
|
||||||
case 16:
|
case 16:
|
||||||
case 17:
|
case 17:
|
||||||
case 18:
|
case 18:
|
||||||
|
|
@ -312,9 +322,9 @@ static void skipToNextNalOrEnd(PBUFFER_DESC buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop until we find an Annex B start sequence (3 or 4 byte)
|
// Loop until we find an Annex B start sequence (3 or 4 byte)
|
||||||
while (!getAnnexBStartSequence(buffer, &startSeq)) {
|
while (!getAnnexBStartSequence(buffer, NULL)) {
|
||||||
if (buffer->length == 0) {
|
if (buffer->length == 0) {
|
||||||
// Reach the end of the buffer
|
// Reached the end of the buffer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -514,17 +524,14 @@ static void queueFragment(PLENTRY_INTERNAL* existingEntry, char* data, int offse
|
||||||
|
|
||||||
// Process an RTP Payload using the slow path that handles multiple NALUs per packet
|
// Process an RTP Payload using the slow path that handles multiple NALUs per packet
|
||||||
static void processRtpPayloadSlow(PBUFFER_DESC currentPos, PLENTRY_INTERNAL* existingEntry) {
|
static void processRtpPayloadSlow(PBUFFER_DESC currentPos, PLENTRY_INTERNAL* existingEntry) {
|
||||||
BUFFER_DESC startSeq;
|
|
||||||
|
|
||||||
// We should not have any NALUs when processing the first packet in an IDR frame
|
// We should not have any NALUs when processing the first packet in an IDR frame
|
||||||
LC_ASSERT(nalChainHead == NULL);
|
LC_ASSERT(nalChainHead == NULL);
|
||||||
LC_ASSERT(nalChainTail == NULL);
|
LC_ASSERT(nalChainTail == NULL);
|
||||||
|
|
||||||
while (currentPos->length != 0) {
|
while (currentPos->length != 0) {
|
||||||
// Skip through any padding bytes
|
// Skip through any padding bytes
|
||||||
if (!getAnnexBStartSequence(currentPos, &startSeq)) {
|
if (!getAnnexBStartSequence(currentPos, NULL)) {
|
||||||
skipToNextNal(currentPos);
|
skipToNextNal(currentPos);
|
||||||
getAnnexBStartSequence(currentPos, &startSeq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip any prepended AUD or SEI NALUs. We may have padding between
|
// Skip any prepended AUD or SEI NALUs. We may have padding between
|
||||||
|
|
@ -544,7 +551,7 @@ static void processRtpPayloadSlow(PBUFFER_DESC currentPos, PLENTRY_INTERNAL* exi
|
||||||
// Now we're decoding a frame
|
// Now we're decoding a frame
|
||||||
decodingFrame = true;
|
decodingFrame = true;
|
||||||
|
|
||||||
if (isSeqReferenceFrameStart(&startSeq)) {
|
if (isSeqReferenceFrameStart(currentPos)) {
|
||||||
// No longer waiting for an IDR frame
|
// No longer waiting for an IDR frame
|
||||||
waitingForIdrFrame = false;
|
waitingForIdrFrame = false;
|
||||||
|
|
||||||
|
|
@ -563,7 +570,7 @@ static void processRtpPayloadSlow(PBUFFER_DESC currentPos, PLENTRY_INTERNAL* exi
|
||||||
if (containsPicData) {
|
if (containsPicData) {
|
||||||
while (currentPos->length != 0) {
|
while (currentPos->length != 0) {
|
||||||
// Any NALUs we encounter on the way to the end of the packet must be reference frame slices
|
// Any NALUs we encounter on the way to the end of the packet must be reference frame slices
|
||||||
LC_ASSERT(getAnnexBStartSequence(currentPos, &startSeq) && isSeqReferenceFrameStart(&startSeq));
|
LC_ASSERT(isSeqReferenceFrameStart(currentPos));
|
||||||
skipToNextNalOrEnd(currentPos);
|
skipToNextNalOrEnd(currentPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue