📄 ra_depack_internal.c
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: ra_depack_internal.c,v 1.1.1.1.2.1 2005/05/04 18:21:33 hubbe Exp $ * * REALNETWORKS CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM * Portions Copyright (c) 1995-2005 RealNetworks, Inc. * All Rights Reserved. * * The contents of this file, and the files included with this file, * are subject to the current version of the Real Format Source Code * Porting and Optimization License, available at * https://helixcommunity.org/2005/license/realformatsource (unless * RealNetworks otherwise expressly agrees in writing that you are * subject to a different license). You may also obtain the license * terms directly from RealNetworks. You may not use this file except * in compliance with the Real Format Source Code Porting and * Optimization License. There are no redistribution rights for the * source code of this file. Please see the Real Format Source Code * Porting and Optimization License for the rights, obligations and * limitations governing use of the contents of the file. * * RealNetworks is the developer of the Original Code and owns the * copyrights in the portions it created. * * This file, and the files included with this file, is distributed and * made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, * EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL * SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT * OR NON-INFRINGEMENT. * * Technology Compatibility Kit Test Suite(s) Location: * https://rarvcode-tck.helixcommunity.org * * Contributor(s): * * ***** END LICENSE BLOCK ***** */#include <stdio.h>#include <string.h>#include <memory.h>#include "helix_types.h"#include "helix_result.h"#include "pack_utils.h"#include "string_utils.h"#include "memory_utils.h"#include "packet_defines.h"#include "codec_defines.h"#include "stream_hdr_utils.h"#include "ra_depack_internal.h"#include "rasl.h"/* Defines */#define TIMESTAMP_GAP_FUDGE_FACTOR 1 /* Maximum non-loss, non-seek gap in ms between packets */#define INITIAL_FRAG_BUFFER_SIZE 2048 /* Initial size of frag buffer */void* ra_depacki_malloc(ra_depack_internal* pInt, UINT32 ulSize){ void* pRet = HXNULL; if (pInt && pInt->fpMalloc) { pRet = pInt->fpMalloc(pInt->pUserMem, ulSize); } return pRet;}void ra_depacki_free(ra_depack_internal* pInt, void* pMem){ if (pInt && pInt->fpFree) { pInt->fpFree(pInt->pUserMem, pMem); }}HX_RESULT ra_depacki_init(ra_depack_internal* pInt, rm_stream_header* hdr){ HX_RESULT retVal = HXR_FAIL; if (pInt && hdr) { /* Initialize local variables */ UINT32 ulTmp = 0; BYTE* pTmp = HXNULL; UINT32 i = 0; /* Check if we have a "HasRelativeTS" property - OK if we don't */ if (HX_SUCCEEDED(rm_stream_get_property_int(hdr, "TrackStartTime", &ulTmp))) { pInt->bForceTrackStartTime = TRUE; pInt->ulTrackStartTime = ulTmp; } /* Check if we have a "ZeroTimeOffset" property - OK if we don't */ if (HX_SUCCEEDED(rm_stream_get_property_int(hdr, "TrackEndTime", &ulTmp))) { pInt->bForceTrackEndTime = TRUE; pInt->ulTrackEndTime = ulTmp; } /* Check if we have an EndTime property */ if (HX_SUCCEEDED(rm_stream_get_property_int(hdr, "EndTime", &ulTmp))) { pInt->bHasEndTime = TRUE; pInt->ulEndTime = ulTmp; } /* Copy the stream duration */ pInt->ulStreamDuration = hdr->ulDuration; /* If we have an end time, then clip the duration */ if (pInt->bHasEndTime && pInt->ulStreamDuration > pInt->ulEndTime) { pInt->ulStreamDuration = pInt->ulEndTime; } /* Check if we have a "RMFF 1.0 Flags" property */ retVal = rm_stream_get_property_buf(hdr, "RMFF 1.0 Flags", &pTmp, &ulTmp); if (retVal == HXR_OK) { /* Parse the "RMFF 1.0 Flags" property */ retVal = ra_depacki_unpack_rule_map(pInt, &pInt->rule2Flag, &pTmp, &ulTmp); if (retVal == HXR_OK) { /* Get the "OpaqueData" property */ retVal = rm_stream_get_property_buf(hdr, "OpaqueData", &pTmp, &ulTmp); if (retVal == HXR_OK) { /* Unpack the opaque data */ retVal = ra_depacki_unpack_opaque_data(pInt, pTmp, ulTmp); } } } } return retVal;}HX_RESULT ra_depacki_unpack_rule_map(ra_depack_internal* pInt, rm_rule_map* pMap, BYTE** ppBuf, UINT32* pulLen){ HX_RESULT retVal = HXR_FAIL; if (pInt) { retVal = rm_unpack_rule_map(ppBuf, pulLen, pInt->fpMalloc, pInt->fpFree, pInt->pUserMem, pMap); } return retVal;}HX_RESULT ra_depacki_unpack_multistream_hdr(ra_depack_internal* pInt, BYTE** ppBuf, UINT32* pulLen){ HX_RESULT retVal = HXR_FAIL; if (pInt) { retVal = rm_unpack_multistream_hdr(ppBuf, pulLen, pInt->fpMalloc, pInt->fpFree, pInt->pUserMem, &pInt->multiStreamHdr); } return retVal;}HX_RESULT ra_depacki_unpack_opaque_data(ra_depack_internal* pInt, BYTE* pBuf, UINT32 ulLen){ HX_RESULT retVal = HXR_FAIL; if (pInt && pBuf && ulLen >= 4) { /* Initialize local variables */ UINT32 ulSize = 0; UINT32 ulID = 0; UINT32 i = 0; UINT32 ulTmp = 0; /* * If the first four bytes are MLTI, then we * know the opaque data contains a multistream header * followed by several normal headers. So first we * need to check the first four bytes. */ ulID = rm_unpack32(&pBuf, &ulLen); /* Now back up 4 bytes */ pBuf -= 4; ulLen += 4; /* Is this a multistream header? */ if (ulID == RM_MULTIHEADER_OBJECT) { /* Unpack the multistream header */ retVal = ra_depacki_unpack_multistream_hdr(pInt, &pBuf, &ulLen); if (retVal == HXR_OK) { pInt->bStreamSwitchable = TRUE; } } else if (ulID == RA_FORMAT_ID) { /* Single-rate stream */ pInt->multiStreamHdr.ulNumSubStreams = 1; /* Clear the stream switchable flag */ pInt->bStreamSwitchable = FALSE; /* Clear the return value */ retVal = HXR_OK; } /* Clean up any existing substream header array */ ra_depacki_cleanup_substream_hdr_array(pInt); /* Set the return value */ retVal = HXR_FAIL; /* Allocate space for substream header array */ ulSize = pInt->multiStreamHdr.ulNumSubStreams * sizeof(ra_substream_hdr); pInt->pSubStreamHdr = (ra_substream_hdr*) ra_depacki_malloc(pInt, ulSize); if (pInt->pSubStreamHdr) { /* NULL out the memory */ memset(pInt->pSubStreamHdr, 0, ulSize); /* Clear the return value */ retVal = HXR_OK; /* Loop through and unpack each substream header */ for (i = 0; i < pInt->multiStreamHdr.ulNumSubStreams && retVal == HXR_OK; i++) { /* Is this a multiheader? */ if (pInt->bStreamSwitchable) { /* * If this is a multistream header, then there * is a 4-byte length in front of every substream header */ if (ulLen >= 4) { ulSize = rm_unpack32(&pBuf, &ulLen); } else { retVal = HXR_FAIL; } } else { /* * If this is not a multi-stream header, then * the rest of the buffer is a single substream header */ ulSize = ulLen; } /* Make sure we have enough parsing buffer */ if (ulLen >= ulSize) { /* Now unpack an substream header */ retVal = ra_depacki_unpack_substream_hdr(pInt, pBuf, ulSize, &pInt->pSubStreamHdr[i]); if (retVal == HXR_OK) { /* Get the substream header */ ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[i]; /* * If the interleaver ID is either VBRS of VBRF, * then this is a VBR stream. */ if (pHdr->ulInterleaverID == RA_INTERLEAVER_VBRS || pHdr->ulInterleaverID == RA_INTERLEAVER_VBRF) { pHdr->bIsVBR = TRUE; } /* Compute the number of codec frames per superblock */ if (pHdr->ulCodecFrameSize) { pHdr->ulNumCodecFrames = pHdr->ulInterleaveBlockSize * pHdr->ulInterleaveFactor / pHdr->ulCodecFrameSize; } /* Compute the ms per block */ if (pHdr->ulBytesPerMin) { pHdr->dBlockDuration = ((double) pHdr->ulInterleaveBlockSize) * 60000.0 / ((double) pHdr->ulBytesPerMin); } /* Compute the superblock size and time */ pHdr->ulSuperBlockSize = pHdr->ulInterleaveBlockSize * pHdr->ulInterleaveFactor; pHdr->ulSuperBlockTime = (UINT32) (pHdr->dBlockDuration * ((double) pHdr->ulInterleaveFactor)); /* Is this stream VBR? */ if (pHdr->bIsVBR) { /* Init the last sent block end time */ pHdr->ulLastSentEndTime = 0; /* * Init the frag buffer members. The frag buffer * willl be set up the first time it is needed. */ pHdr->pFragBuffer = HXNULL; pHdr->ulFragBufferSize = 0; pHdr->ulFragBufferOffset = 0; pHdr->ulFragBufferTime = 0; } else { /* Set the return value */ retVal = HXR_OUTOFMEMORY; /* Set the superblock keyframe time */ pHdr->bHasKeyTime = FALSE; pHdr->ulKeyTime = 0; /* Allocate the interleaved buffer */ pHdr->pIBuffer = (BYTE*) ra_depacki_malloc(pInt, pHdr->ulSuperBlockSize); if (pHdr->pIBuffer) { /* Zero out the buffer */ memset(pHdr->pIBuffer, 0, pHdr->ulSuperBlockSize); /* Allocate the de-interleaved buffer */ pHdr->pDBuffer = (BYTE*) ra_depacki_malloc(pInt, pHdr->ulSuperBlockSize); if (pHdr->pDBuffer) { /* Zero out the buffer */ memset(pHdr->pDBuffer, 0, pHdr->ulSuperBlockSize); /* Allocate the interleaved flags */ ulTmp = pHdr->ulInterleaveFactor * sizeof(UINT32); pHdr->pIPresentFlags = (UINT32*) ra_depacki_malloc(pInt, ulTmp); if (pHdr->pIPresentFlags) { /* Zero out the flags */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -