Encode the final packet length in the frame header for AV1
Some decoders (Android) are very strict about trailing padding bytes.
This commit is contained in:
parent
953971c9a3
commit
190b08ecf4
1 changed files with 16 additions and 4 deletions
|
|
@ -15,6 +15,7 @@ static bool waitingForRefInvalFrame;
|
||||||
static unsigned int lastPacketInStream;
|
static unsigned int lastPacketInStream;
|
||||||
static bool decodingFrame;
|
static bool decodingFrame;
|
||||||
static int frameType;
|
static int frameType;
|
||||||
|
static uint16_t lastPacketPayloadLength;
|
||||||
static bool strictIdrFrameWait;
|
static bool strictIdrFrameWait;
|
||||||
static uint64_t syntheticPtsBase;
|
static uint64_t syntheticPtsBase;
|
||||||
static uint16_t frameHostProcessingLatency;
|
static uint16_t frameHostProcessingLatency;
|
||||||
|
|
@ -69,6 +70,7 @@ void initializeVideoDepacketizer(int pktSize) {
|
||||||
frameHostProcessingLatency = 0;
|
frameHostProcessingLatency = 0;
|
||||||
firstPacketReceiveTime = 0;
|
firstPacketReceiveTime = 0;
|
||||||
firstPacketPresentationTime = 0;
|
firstPacketPresentationTime = 0;
|
||||||
|
lastPacketPayloadLength = 0;
|
||||||
dropStatePending = false;
|
dropStatePending = false;
|
||||||
idrFrameProcessed = false;
|
idrFrameProcessed = false;
|
||||||
strictIdrFrameWait = !isReferenceFrameInvalidationEnabled();
|
strictIdrFrameWait = !isReferenceFrameInvalidationEnabled();
|
||||||
|
|
@ -702,7 +704,7 @@ void requestDecoderRefresh(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return 1 if packet is the first one in the frame
|
// Return 1 if packet is the first one in the frame
|
||||||
static int isFirstPacket(uint8_t flags, uint8_t fecBlockNumber) {
|
static bool isFirstPacket(uint8_t flags, uint8_t fecBlockNumber) {
|
||||||
// Clear the picture data flag
|
// Clear the picture data flag
|
||||||
flags &= ~FLAG_CONTAINS_PIC_DATA;
|
flags &= ~FLAG_CONTAINS_PIC_DATA;
|
||||||
|
|
||||||
|
|
@ -718,7 +720,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||||
BUFFER_DESC currentPos;
|
BUFFER_DESC currentPos;
|
||||||
uint32_t frameIndex;
|
uint32_t frameIndex;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint32_t firstPacket;
|
bool firstPacket, lastPacket;
|
||||||
uint32_t streamPacketIndex;
|
uint32_t streamPacketIndex;
|
||||||
uint8_t fecCurrentBlockNumber;
|
uint8_t fecCurrentBlockNumber;
|
||||||
uint8_t fecLastBlockNumber;
|
uint8_t fecLastBlockNumber;
|
||||||
|
|
@ -736,6 +738,7 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||||
frameIndex = videoPacket->frameIndex;
|
frameIndex = videoPacket->frameIndex;
|
||||||
flags = videoPacket->flags;
|
flags = videoPacket->flags;
|
||||||
firstPacket = isFirstPacket(flags, fecCurrentBlockNumber);
|
firstPacket = isFirstPacket(flags, fecCurrentBlockNumber);
|
||||||
|
lastPacket = (flags & FLAG_EOF) && fecCurrentBlockNumber == fecLastBlockNumber;
|
||||||
|
|
||||||
LC_ASSERT((flags & ~(FLAG_SOF | FLAG_EOF | FLAG_CONTAINS_PIC_DATA)) == 0);
|
LC_ASSERT((flags & ~(FLAG_SOF | FLAG_EOF | FLAG_CONTAINS_PIC_DATA)) == 0);
|
||||||
|
|
||||||
|
|
@ -864,6 +867,14 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||||
BbGet16(&bb, &frameHostProcessingLatency);
|
BbGet16(&bb, &frameHostProcessingLatency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Codecs like H.264 and HEVC handle the FEC trailing zero padding just fine, but other
|
||||||
|
// codecs need the exact length encoded separately.
|
||||||
|
if (!(NegotiatedVideoFormat & (VIDEO_FORMAT_MASK_H264 | VIDEO_FORMAT_MASK_H265))) {
|
||||||
|
BYTE_BUFFER bb;
|
||||||
|
BbInitializeWrappedBuffer(&bb, currentPos.data, currentPos.offset + 4, 2, BYTE_ORDER_LITTLE);
|
||||||
|
BbGet16(&bb, &lastPacketPayloadLength);
|
||||||
|
}
|
||||||
|
|
||||||
if (APP_VERSION_AT_LEAST(7, 1, 450)) {
|
if (APP_VERSION_AT_LEAST(7, 1, 450)) {
|
||||||
// >= 7.1.450 uses 2 different header lengths based on the first byte:
|
// >= 7.1.450 uses 2 different header lengths based on the first byte:
|
||||||
// 0x01 indicates an 8 byte header
|
// 0x01 indicates an 8 byte header
|
||||||
|
|
@ -976,10 +987,11 @@ static void processRtpPayload(PNV_VIDEO_PACKET videoPacket, int length,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Other codecs are just passed through as is.
|
// Other codecs are just passed through as is.
|
||||||
queueFragment(existingEntry, currentPos.data, currentPos.offset, currentPos.length);
|
queueFragment(existingEntry, currentPos.data, currentPos.offset,
|
||||||
|
lastPacket ? lastPacketPayloadLength : currentPos.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & FLAG_EOF) && fecCurrentBlockNumber == fecLastBlockNumber) {
|
if (lastPacket) {
|
||||||
// Move on to the next frame
|
// Move on to the next frame
|
||||||
decodingFrame = false;
|
decodingFrame = false;
|
||||||
nextFrameNumber = frameIndex + 1;
|
nextFrameNumber = frameIndex + 1;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue