📄 ra_depack_internal.c
字号:
} ulBlockNum = (UINT32) (dBlockNum + 0.5); /* Is this block beyond our superblock? */ if (ulBlockNum >= pHdr->ulInterleaveFactor) { /* * We must have had loss at the end of the * previous superblock, since we have received * a packet in the next superblock without having * sent the current superblock. Therefore, we attempt * to finish out the current superblock and send it. */ retVal = ra_depacki_deinterleave_send(pInt, ulSubStream); if (retVal == HXR_OK) { /* Now we need to update the block index */ if (bKey) { /* * This packet is a keyframe packet, so * we simply assign the new time and set * the block index to 0. */ pHdr->ulKeyTime = pPacket->ulTime; ulBlockNum = 0; } else { /* * This is not a keyframe packet, so we need to * keep adding the superblock time to the key time * and keep subtracting interleave factor to the block * index until we reach the range [0,intereaveFactor-1] * for the index. */ do { pHdr->ulKeyTime += pHdr->ulSuperBlockTime; ulBlockNum -= pHdr->ulInterleaveFactor; } while (ulBlockNum < pHdr->ulInterleaveFactor); } } } /* Sanity check on buffer copy parameters */ if (ulBlockNum < pHdr->ulInterleaveFactor && ((UINT32) pPacket->usDataLen) == pHdr->ulInterleaveBlockSize && pHdr->pIPresentFlags) { /* Copy the data into the interleave buffer */ memcpy(pHdr->pIBuffer + ulBlockNum * pHdr->ulInterleaveBlockSize, pPacket->pData, pHdr->ulInterleaveBlockSize); /* Set all the flags to be present for this block */ pHdr->pIPresentFlags[ulBlockNum] = 0xFFFFFFFF; /* Increment the block count in this superblock */ pHdr->ulBlockCount++; /* Is this the last block in the superblock? */ if (ulBlockNum == pHdr->ulInterleaveFactor - 1) { /* Deinterleave and send the blocks */ retVal = ra_depacki_deinterleave_send(pInt, ulSubStream); } else { /* Not ready to send yet. Clear the return */ retVal = HXR_OK; } } } else { /* * We don't have a key block time or the key block time * that we have is greater than the packet time, so we * can't compute what slot this block should be in. This * probably occurred because of loss at the beginning of the * stream. We have to throw this packet away. */ retVal = HXR_OK; } } else { /* * The packet was lost. For now, don't do anything * with the packet. We will deduce loss based entirely * on timestamps for now. */ retVal = HXR_OK; } /* Save the information about the last packet */ pHdr->lastPacket.ulTime = pPacket->ulTime; pHdr->lastPacket.usStream = pPacket->usStream; pHdr->lastPacket.usASMFlags = pPacket->usASMFlags; pHdr->lastPacket.ucASMRule = pPacket->ucASMRule; pHdr->lastPacket.ucLost = pPacket->ucLost; pHdr->bHasLastPacket = TRUE; } return retVal;}HX_RESULT ra_depacki_parse_vbr_packet(ra_depack_internal* pInt, rm_packet* pPacket, UINT32* pulNumAU, HXBOOL* pbFragmented, UINT32* pulAUSize, UINT32* pulAUFragSize){ HX_RESULT retVal = HXR_FAIL; if (pInt && pPacket && pulNumAU && pbFragmented && pulAUSize && pulAUFragSize && pPacket->pData && pPacket->usDataLen) { /* Init local variables */ BYTE* pBuf = pPacket->pData; UINT32 ulSize = pPacket->usDataLen; UINT32 ulPacketSize = ulSize; UINT32 ulAUHeaderSizeBits = 0; UINT32 ulAUHeaderSize = 0; UINT32 ulNumAU = 0; UINT32 ulAUSize = 0; UINT32 ulAUSizeTotal = 0; UINT32 i = 0; UINT32 ulExpectedSize = 0; /* Sanity check on size */ if (ulSize >= 2) { /* Get the AU header size in bits */ ulAUHeaderSizeBits = rm_unpack16(&pBuf, &ulSize); /* Convert to bytes (rounding up to next byte) */ ulAUHeaderSize = (ulAUHeaderSizeBits + 7) >> 3; /* * Sanity check to make sure that the AU header size is * greater than 0 and a multiple of 2 bytes */ if (ulAUHeaderSize && !(ulAUHeaderSize & 1)) { /* * Since we know that each AU header is 2 bytes, then * we know that the number of AU's in this packet is * ulAUHeaderSize / 2. */ ulNumAU = ulAUHeaderSize >> 1; /* * The audio/mpeg-generic spec says that each packet * can either have a complete AU, a fragment of a single * AU, or multiple complete AUs. Therefore, if the * number of AUs is greater than 1, then we know we * have ulNumAU *complete* AUs. Therefore, for more * than one AU, we know what the exact size of the * packet should be, and that should match up with * the data size of the packet. */ retVal = HXR_OK; for (i = 0; i < ulNumAU && retVal == HXR_OK; i++) { if (ulSize >= 2) { ulAUSize = rm_unpack16(&pBuf, &ulSize); ulAUSizeTotal += ulAUSize; } else { retVal = HXR_FAIL; } } if (retVal == HXR_OK) { /* Compute the expected size of the packet */ ulExpectedSize = 2 + /* AU header size (16 bits) */ ulNumAU * 2 + /* AU sizes */ ulAUSizeTotal; /* the AU's themselves */ /* * Check this against the actual size. If we have * 1 AU, then the expected size can be greater than * the actual size due to fragmentation. If we have * more than more AU, then the expected size MUST * match the actual size. */ if (ulNumAU > 1) { if (ulExpectedSize == ulPacketSize) { /* Multiple AUs, no fragmentation */ *pbFragmented = FALSE; } else { /* Something wrong */ retVal = HXR_FAIL; } } else if (ulNumAU == 1) { if (ulExpectedSize > ulPacketSize) { /* Fragmented single AU */ *pbFragmented = TRUE; } else { /* Single AU, no fragmentation */ *pbFragmented = FALSE; } /* Set the AU size */ *pulAUSize = ulAUSizeTotal; *pulAUFragSize = ulPacketSize - 4; } /* Assign the number of AU out parameter */ if (retVal == HXR_OK) { *pulNumAU = ulNumAU; } } } } } return retVal;}HX_RESULT ra_depacki_generate_and_send_loss(ra_depack_internal* pInt, UINT32 ulSubStream, UINT32 ulFirstStartTime, UINT32 ulLastEndTime){ HX_RESULT retVal = HXR_FAIL; if (pInt && ulSubStream < pInt->multiStreamHdr.ulNumSubStreams && ulLastEndTime > ulFirstStartTime) { HXDOUBLE dAUDuration = pInt->pSubStreamHdr[ulSubStream].dBlockDuration; HXDOUBLE dDiff = ulLastEndTime - ulFirstStartTime; UINT32 ulNumLossPackets = 0; UINT32 i = 0; UINT32 ulTSOffset = 0; UINT32 ulTime = 0; /* Compute the number of packets */ if (dAUDuration != 0.0) { ulNumLossPackets = (UINT32) (dDiff / dAUDuration); } /* Clear the return value */ retVal = HXR_OK; /* Generate loss packets */ for (i = 0; i < ulNumLossPackets && HX_SUCCEEDED(retVal); i++) { ulTSOffset = (UINT32) (i * dAUDuration); ulTime = ulFirstStartTime + ulTSOffset; retVal = ra_depacki_send_block(pInt, ulSubStream, HXNULL, 0, ulTime, 0); /* Flags of 0 indicate loss */ } } return retVal;}HX_RESULT ra_depacki_send_block(ra_depack_internal* pInt, UINT32 ulSubStream, BYTE* pBuf, UINT32 ulLen, UINT32 ulTime, UINT32 ulFlags){ HX_RESULT retVal = HXR_FAIL; if (pInt && pInt->fpAvail) { /* Allocate space for a ra_block structure */ ra_block* pBlock = ra_depacki_malloc(pInt, sizeof(ra_block)); if (pBlock) { /* Zero out the memory */ memset(pBlock, 0, sizeof(ra_block)); /* Clear the return value */ retVal = HXR_OK; /* Copy the buffer */ if (pBuf && ulLen) { pBlock->pData = copy_buffer(pInt->pUserMem, pInt->fpMalloc, pBuf, ulLen); if (pBlock->pData) { pBlock->ulDataLen = ulLen; } else { retVal = HXR_OUTOFMEMORY; } } if (retVal == HXR_OK) { /* Assign the timestamp and flags */ pBlock->ulTimestamp = ulTime; pBlock->ulDataFlags = ulFlags; /* Send the block */ retVal = pInt->fpAvail(pInt->pAvail, ulSubStream, pBlock); } } } return retVal;}HX_RESULT ra_depacki_handle_frag_packet(ra_depack_internal* pInt, UINT32 ulSubStream, rm_packet* pPacket, UINT32 ulAUSize, UINT32 ulAUFragSize){ HX_RESULT retVal = HXR_FAIL; if (pInt && pInt->pSubStreamHdr && pPacket && ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) { UINT32 ulPacketSize = (UINT32) pPacket->usDataLen; UINT32 ulPacketOffset = (ulPacketSize >= ulAUFragSize ? ulPacketSize - ulAUFragSize : 0); /* Get the substream header */ ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -