📄 ra_depack_internal.c
字号:
/* Clear the return value */ retVal = HXR_OK; /* Have we allocated the frag buffer yet? */ if (!pHdr->pFragBuffer) { retVal = ra_depacki_init_frag_buffer(pInt, pHdr); } if (HX_SUCCEEDED(retVal)) { /* * Do we have a current fragment, and if so, is it * a different timestamp from this fragment? */ if (pHdr->bHasFrag && pHdr->ulFragBufferTime != pPacket->ulTime) { /* Clear the frag buffer */ ra_depacki_clear_frag_buffer(pInt, pHdr); } /* * Are we currently processing a fragment? If not, * then initialize this fragment, resizing the * buffer if necessary. */ if (!pHdr->bHasFrag) { /* Make sure the buffer size is big enough */ if (ulAUSize > pHdr->ulFragBufferSize) { retVal = ra_depacki_resize_frag_buffer(pInt, pHdr, ulAUSize); } if (HX_SUCCEEDED(retVal)) { /* Init the members for this fragment */ pHdr->ulFragBufferOffset = 0; pHdr->ulFragBufferTime = pPacket->ulTime; pHdr->ulFragBufferAUSize = ulAUSize; pHdr->bHasFrag = TRUE; } } if (HX_SUCCEEDED(retVal)) { /* Make sure we have room for the memcpy */ if (pHdr->ulFragBufferOffset + ulAUFragSize <= pHdr->ulFragBufferSize && ulPacketOffset + ulAUFragSize <= ulPacketSize) { /* Copy this buffer in */ memcpy(pHdr->pFragBuffer + pHdr->ulFragBufferOffset, pPacket->pData + ulPacketOffset, ulAUFragSize); /* Update the frag buffer offset */ pHdr->ulFragBufferOffset += ulAUFragSize; /* Have we finished the fragmented AU? */ if (pHdr->ulFragBufferOffset >= pHdr->ulFragBufferAUSize) { /* Send the frag buffer */ retVal = ra_depacki_send_block(pInt, ulSubStream, pHdr->pFragBuffer, pHdr->ulFragBufferAUSize, pHdr->ulFragBufferTime, 0xFFFFFFFF); /* Whether we succeed or not, clear the frag buffer */ ra_depacki_clear_frag_buffer(pInt, pHdr); } } else { retVal = HXR_FAIL; } } } } return retVal;}HX_RESULT ra_depacki_handle_nonfrag_packet(ra_depack_internal* pInt, UINT32 ulSubStream, rm_packet* pPacket, UINT32 ulNumAU){ HX_RESULT retVal = HXR_FAIL; if (pInt && pInt->pSubStreamHdr && pPacket && ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) { /* Init the local variables */ UINT32 ulAUDataSizeSum = 0; UINT32 i = 0; BYTE* pBuf = pPacket->pData; UINT32 ulLen = pPacket->usDataLen; UINT32 ulTSOffset = 0; UINT32 ulAUSize = 0; UINT32 ulBufOffset = 0; /* Get the substream header */ ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream]; /* * We can clear the frag queue. If there was no * loss in the last fragmented AU, then it was * cleared after the packet was created. If there * WAS loss in the last fragmented AU, then we * just handled it by generating loss packets. */ ra_depacki_clear_frag_buffer(pInt, pHdr); /* Clear the return value */ retVal = HXR_OK; /* Step through the packet sending blocks */ for (i = 0; i < ulNumAU && HX_SUCCEEDED(retVal); i++) { /* Set the return value */ retVal = HXR_FAIL; /* Compute the time offset for this block */ ulTSOffset = (UINT32) (i * pHdr->dBlockDuration); /* Compute the buffer offset for the AU size */ ulBufOffset = 2 + (i << 1); /* Sanity check on packet size */ if (ulBufOffset + 1 < ulLen) { /* Parse out the size of this AU */ ulAUSize = rm_unpack16_nse(pBuf + ulBufOffset, ulLen - ulBufOffset); /* Compute the offset of the AU */ ulBufOffset = 2 + ulNumAU * 2 + ulAUDataSizeSum; /* Sanity check on size */ if (ulBufOffset + ulAUSize <= ulLen) { /* Send this AU */ retVal = ra_depacki_send_block(pInt, ulSubStream, pBuf + ulBufOffset, ulAUSize, pPacket->ulTime + ulTSOffset, 0xFFFFFFFF); if (retVal == HXR_OK) { /* Update the AU data size sum */ ulAUDataSizeSum += ulAUSize; } } } } if (HX_SUCCEEDED(retVal)) { /* Update the end time of the last block sent */ ulTSOffset = (UINT32) (ulNumAU * pHdr->dBlockDuration); pHdr->ulLastSentEndTime = pPacket->ulTime + ulTSOffset; } } return retVal;}HX_RESULT ra_depacki_init_frag_buffer(ra_depack_internal* pInt, ra_substream_hdr* pHdr){ HX_RESULT retVal = HXR_FAIL; if (pInt && pHdr && !pHdr->pFragBuffer) { /* Allocate the frag buffer */ pHdr->pFragBuffer = ra_depacki_malloc(pInt, INITIAL_FRAG_BUFFER_SIZE); if (pHdr->pFragBuffer) { /* Zero out the buffer */ memset(pHdr->pFragBuffer, 0, INITIAL_FRAG_BUFFER_SIZE); /* Init the members */ pHdr->ulFragBufferSize = INITIAL_FRAG_BUFFER_SIZE; pHdr->ulFragBufferTime = 0; pHdr->ulFragBufferOffset = 0; pHdr->ulFragBufferAUSize = 0; pHdr->bHasFrag = FALSE; } } return retVal;}HX_RESULT ra_depacki_resize_frag_buffer(ra_depack_internal* pInt, ra_substream_hdr* pHdr, UINT32 ulNewSize){ HX_RESULT retVal = HXR_FAIL; if (pInt && pHdr && pHdr->pFragBuffer) { /* Allocate a new buffer */ BYTE* pNewBuf = ra_depacki_malloc(pInt, ulNewSize); if (pNewBuf) { /* Copy the old buffer */ if (pHdr->ulFragBufferOffset) { memcpy(pNewBuf, pHdr->pFragBuffer, pHdr->ulFragBufferOffset); } /* NULL out the rest of the buffer */ memset(pNewBuf + pHdr->ulFragBufferOffset, 0, ulNewSize - pHdr->ulFragBufferOffset); /* Free the old buffer */ ra_depacki_free(pInt, pHdr->pFragBuffer); /* Assign the members. We won't change time or offset */ pHdr->pFragBuffer = pNewBuf; pHdr->ulFragBufferSize = ulNewSize; /* Clear the return value */ retVal = HXR_OK; } } return retVal;}void ra_depacki_clear_frag_buffer(ra_depack_internal* pInt, ra_substream_hdr* hdr){ if (pInt && hdr && hdr->bHasFrag) { /* Clear the frag buffer members */ hdr->bHasFrag = FALSE; hdr->ulFragBufferAUSize = 0; hdr->ulFragBufferOffset = 0; hdr->ulFragBufferTime = 0; }}HX_RESULT ra_depacki_seek(ra_depack_internal* pInt, UINT32 ulTime){ HX_RESULT retVal = HXR_FAIL; if (pInt && pInt->pSubStreamHdr) { /* * Loop through all the substream headers * and set the bSeeked flag. */ UINT32 i = 0; for (i = 0; i < pInt->multiStreamHdr.ulNumSubStreams; i++) { pInt->pSubStreamHdr[i].bSeeked = TRUE; } } return retVal;}HX_RESULT ra_depacki_deinterleave_send(ra_depack_internal* pInt, UINT32 ulSubStream){ HX_RESULT retVal = HXR_FAIL; if (pInt && pInt->pSubStreamHdr && ulSubStream < pInt->multiStreamHdr.ulNumSubStreams && pInt->fpAvail) { /* Init local variables */ UINT32 i = 0; UINT32 ulTimeOffset = 0; UINT32 ulTimestamp = 0; HXDOUBLE dTimeOffset = 0.0; ra_block* pBlock = HXNULL; /* Deinterleave the superblock */ retVal = ra_depacki_deinterleave(pInt, ulSubStream); if (retVal == HXR_OK) { /* Get the substream header */ ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream]; /* Send the blocks from the deinterleave buffer */ for (i = 0; i < pHdr->ulBlockCount && HX_SUCCEEDED(retVal); i++) { /* Set the return value */ retVal = HXR_OUTOFMEMORY; /* Compute the time offset for this block */ dTimeOffset = i * pHdr->dBlockDuration; ulTimeOffset = (UINT32) dTimeOffset; ulTimestamp = pHdr->ulKeyTime + ulTimeOffset; /* Make sure the time is less than the stream duration */ if (ulTimestamp <= pInt->ulStreamDuration) { /* Create the ra_block structure */ pBlock = (ra_block*) ra_depacki_malloc(pInt, sizeof(ra_block)); if (pBlock) { /* Alloc and copy the buffer */ pBlock->pData = copy_buffer(pInt->pUserMem, pInt->fpMalloc, pHdr->pDBuffer + i * pHdr->ulInterleaveBlockSize, pHdr->ulInterleaveBlockSize); if (pBlock->pData) { pBlock->ulDataLen = pHdr->ulInterleaveBlockSize; pBlock->ulTimestamp = ulTimestamp; pBlock->ulDataFlags = pHdr->pDPresentFlags[i]; /* Send the block */ retVal = pInt->fpAvail(pInt->pAvail, ulSubStream, pBlock); } } } else { /* * Block is after the stream duration, so clear * the return value and break out of the loop. */ retVal = HXR_OK; break; } } /* Clear the interleaving buffers */ memset(pHdr->pIBuffer, 0, pHdr->ulSuperBlockSize); memset(pHdr->pDBuffer, 0, pHdr->ulSuperBlockSize); memset(pHdr->pIPresentFlags, 0, pHdr->ulInterleaveFactor * sizeof(UINT32)); memset(pHdr->pDPresentFlags, 0, pHdr->ulInterleaveFactor * sizeof(UINT32)); /* Clear the state */ pHdr->bHasKeyTime = FALSE; pHdr->ulKeyTime = 0; pHdr->ulBlockCount = 0; } } return retVal;}HX_RESULT ra_depacki_deinterleave(ra_depack_internal* pInt, UINT32 ulSubStream){ HX_RESULT retVal = HXR_FAIL; if (pInt && pInt->pSubStreamHdr && ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) { /* Get the interleaver ID */ UINT32 ulID = pInt->pSub
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -