📄 mpeg_demux.cpp
字号:
}
/**
* MPEG_ScanForAndSkipStartCode Function. Scans the MPEG stream for the next
* valid start code. This start code, once found, is stored in the Demux
* information structure and the MPEG data stream pointer is updated
* appropriately.
*
* @param
* DEMUXINFO *pDemuxInfo - Demux information
*
* @retval
* None.
*
* @verified
* No.
*/
static void MPEG_ScanForAndSkipStartCode( DEMUXINFO *pDemuxInfo )
{
BYTE bStartCodePtr[MPEG_START_CODE_LENGTH] = {0};
BYTE bWrapDataPtr[3] = {0};
BYTE bWrapOffset = 0;
ULONG ulDataNeeded = 0;
ULONG ulWrapDataLength = 0;
ULONG ulStartCode = 0;
ULONG ulSkipBytes;
BOOLEAN fFoundStartCode = FALSE;
static BOOLEAN fFirstStartCode = TRUE;
static BOOLEAN fHadToScan = FALSE;
static ULONG ulLastStartCode = 0;
/* Search for a valid start code */
while (FALSE == fFoundStartCode)
{
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
DBGPRINT(DBG_MPEG_DEMUX, ("MPEG_ScanForAndSkipStartCode: ABORTED\n"));
return;
}
/* If there is zero bytes of data left, wait for
* more data, then look for a start code. */
if (0 == pDemuxInfo->ulDataLength)
{
MPEG_WaitForMoreData(pDemuxInfo);
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
return;
}
}
/* If there is less than four bytes of data left, grab the remaining
* data as wrap data and use it to look for a start code. */
else if (pDemuxInfo->ulDataLength < MPEG_START_CODE_LENGTH)
{
/* Grab the wrap data and the wrap data length. */
ulWrapDataLength = pDemuxInfo->ulDataLength;
memcpy(bWrapDataPtr, pDemuxInfo->pbData, ulWrapDataLength);
MPEG_DemuxInfoUpdate(pDemuxInfo, ulWrapDataLength, UPDATE_NONE, __LINE__);
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
return;
}
/* Use the wrap data to look for a start code. */
while ( (ulWrapDataLength != 0) && !fFoundStartCode )
{
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
return;
}
ulDataNeeded = MPEG_START_CODE_LENGTH - ulWrapDataLength;
memcpy(bStartCodePtr, &bWrapDataPtr[bWrapOffset], ulWrapDataLength);
memcpy(bStartCodePtr + ulWrapDataLength, pDemuxInfo->pbData, ulDataNeeded);
ulStartCode = MAKE_DWORD( bStartCodePtr );
if ( COULD_BE_START_CODE(ulStartCode) == TRUE)
{
/* Verify we've found a valid start code. */
if ( TRUE == MPEG_IsStartCodeValid(ulStartCode) )
{
#if ENABLE_DEMUX_REMAP_FEATURE
/* Remap the stream ID in the stream, if necessary. */
if ( pDemuxInfo->tConfigInfo.bRemapStreamID == (BYTE)(ulStartCode & 0x000000ff) )
{
DBGPRINT(DBG_ON(DBG_TRACE), ("MPEG_ScanForAndSkipStartCode(1): BEFORE (0x%02x)\n",
*(pDemuxInfo->pbData + ulDataNeeded - 1)));
*(pDemuxInfo->pbData + ulDataNeeded - 1) = pDemuxInfo->tConfigInfo.bRemapStreamIDValue;
DBGPRINT(DBG_ON(DBG_TRACE), ("MPEG_ScanForAndSkipStartCode(1): AFTER (0x%02x)\n",
*(pDemuxInfo->pbData + ulDataNeeded - 1)));
}
#endif
fFoundStartCode = TRUE;
MPEG_DemuxInfoUpdate(pDemuxInfo, ulDataNeeded, UPDATE_NONE, __LINE__);
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
return;
}
}
}
/* Did not find a valid start code, look at the next group of four bytes. */
if (fFoundStartCode == FALSE)
{
if (FALSE == fHadToScan)
{
fHadToScan = TRUE;
}
ulWrapDataLength--;
bWrapOffset++;
}
memset( bStartCodePtr, 0, MPEG_START_CODE_LENGTH );
}
/* Clear the wrap data. */
memset( bWrapDataPtr, 0, 3 );
}
/* There is enough data to look for a start code. */
else
{
/* Read and return the next four bytes. */
ulStartCode = MAKE_DWORD( pDemuxInfo->pbData );
if ( COULD_BE_START_CODE(ulStartCode) == TRUE)
{
/* Verify we've found a valid start code. */
if ( TRUE == MPEG_IsStartCodeValid(ulStartCode) )
{
#if ENABLE_DEMUX_REMAP_FEATURE
/* Remap the stream ID in the stream, if necessary. */
if ( pDemuxInfo->tConfigInfo.bRemapStreamID == (BYTE)(ulStartCode & 0x000000ff) )
{
DBGPRINT(DBG_ON(DBG_TRACE), ("MPEG_ScanForAndSkipStartCode(2): BEFORE (0x%02x)\n",
*(pDemuxInfo->pbData + MPEG_START_CODE_LENGTH - 1)));
*(pDemuxInfo->pbData + MPEG_START_CODE_LENGTH - 1) = pDemuxInfo->tConfigInfo.bRemapStreamIDValue;
DBGPRINT(DBG_ON(DBG_TRACE), ("MPEG_ScanForAndSkipStartCode(2): AFTER (0x%02x)\n",
*(pDemuxInfo->pbData + MPEG_START_CODE_LENGTH - 1)));
}
#endif
fFoundStartCode = TRUE;
MPEG_DemuxInfoUpdate(pDemuxInfo, MPEG_START_CODE_LENGTH, UPDATE_NONE, __LINE__);
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
return;
}
}
}
/* Did not find a valid start code, look at the next group of four bytes. */
if (fFoundStartCode == FALSE)
{
if( (CSS == pDemuxInfo->tDataEncryption) && (MPEG_PACK_HEADER_START_CODE != ulLastStartCode) )
{
ulSkipBytes = 2048 - ((ULONG)pDemuxInfo->pbData - (ULONG)pDemuxInfo->pbPack);
MPEG_DemuxInfoUpdate(pDemuxInfo, ulSkipBytes, UPDATE_NONE, __LINE__);
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
return;
}
}
else
{
if (FALSE == fHadToScan)
{
fHadToScan = TRUE;
}
MPEG_DemuxInfoUpdate(pDemuxInfo, 1, UPDATE_NONE, __LINE__);
if (pDemuxInfo->pDynamicConfigInfo->ulDemuxState != DEMUX_STARTED)
{
return;
}
}
}
}
}
/* Notify scanning done, if necessary. */
if (TRUE == fHadToScan)
{
MPEG_StreamDump(pDemuxInfo);
fHadToScan = FALSE;
}
/* Print out the first valid start code. */
if (TRUE == fFirstStartCode)
{
fFirstStartCode = FALSE;
}
/* Save the start code just found. */
ulLastStartCode = ulStartCode;
/* Return the valid start code and associated PES ID */
pDemuxInfo->ulStartCode = ulStartCode;
pDemuxInfo->bPesID = (BYTE)(ulStartCode & 0x000000ff);
}
/**
* MPEG_IsStreamDesired Function. Examines the current start code to see if the
* stream is desired. This is determined by looking at the Demux configuration
* data.
*
* @param
* DEMUXINFO *pDemuxInfo - Demux information
*
* @retval
* TRUE if the stream is desired
* FALSE if the stream is not desired
*
* @verified
* No.
*/
static BOOLEAN MPEG_IsStreamDesired( DEMUXINFO *pDemuxInfo )
{
BOOLEAN fRetVal = FALSE;
/* If the last start code fetched was that of a pack header or a system
* header, always return TRUE. */
if ((pDemuxInfo->ulStartCode == MPEG_PACK_HEADER_START_CODE) ||
(pDemuxInfo->ulStartCode == MPEG_SYSTEM_HEADER_START_CODE) )
{
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("MPEG_IsStreamDesired: TRUE -- ID=%x\n", pDemuxInfo->ulStartCode));
#endif
return TRUE;
}
/*
* Examine the configuration data to see if the stream is desired
*/
for (int i = 0; i < pDemuxInfo->tConfigInfo.iOutputPinCount; i++)
{
if (pDemuxInfo->tConfigInfo.tOutputPin[i].bPesID == pDemuxInfo->bPesID)
{
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("MPEG_IsStreamDesired: TRUE -- ID=%x, PesID=%x\n", pDemuxInfo->ulStartCode, pDemuxInfo->bPesID));
#endif
fRetVal = TRUE;
break;
}
else
{
fRetVal = FALSE;
}
}
/* Return whether or not the stream is desired */
return (fRetVal);
}
/**
* MPEG_IdentifyStream Function. Uses the current start code to determine
* which parse state to move to.
*
* @param
* DEMUXINFO *pDemuxInfo - Demux information
*
* @retval
* None.
*
* @remark
* This function will need to scan through the Demux output pins to
* see if the identified stream is needed. May need a skip stream state
* to skip over a stream if it is not desired.
*
* @verified
* No.
*/
static void MPEG_IdentifyStream( DEMUXINFO *pDemuxInfo )
{
switch( pDemuxInfo->ulStartCode )
{
case MPEG_PACK_HEADER_START_CODE:
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("*** PACK_HEADER ***\n"));
#endif
pDemuxInfo->pbPack = (pDemuxInfo->pbData - 4);
pDemuxInfo->pbPacket = pDemuxInfo->pbPack;
pDemuxInfo->ulDemuxState = PACK_HEADER;
break;
case MPEG_SYSTEM_HEADER_START_CODE:
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("*** SYSTEM_HEADER ***\n"));
#endif
pDemuxInfo->ulDemuxState = SYSTEM_HEADER;
break;
case MPEG_PADDING_STREAM_START_CODE:
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("*** PADDING_STREAM ***\n"));
#endif
pDemuxInfo->ulDemuxState = PADDING_STREAM;
break;
case MPEG_PRIVATE_STREAM_1_START_CODE:
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("*** PRIVATE_STREAM_1 ***\n"));
#endif
pDemuxInfo->ulDemuxState = PRIVATE_STREAM_1;
pDemuxInfo->pbPacket = (pDemuxInfo->pbData - 4);
break;
case MPEG_PRIVATE_STREAM_2_START_CODE:
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("*** PRIVATE_STREAM_2 ***\n"));
#endif
pDemuxInfo->ulDemuxState = PRIVATE_STREAM_2;
pDemuxInfo->pbPacket = (pDemuxInfo->pbData - 4);
break;
case MPEG_PROGRAM_STREAM_MAP_START_CODE:
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("*** PROGRAM_STREAM_MAP ***\n"));
#endif
pDemuxInfo->ulDemuxState = SKIP_STREAM;
break;
default:
if( (pDemuxInfo->ulStartCode >= MPEG_AUDIO1_PACKET_START_CODE_BEGIN) &&
(pDemuxInfo->ulStartCode <= MPEG_AUDIO1_PACKET_START_CODE_END) )
{
pDemuxInfo->ulDemuxState = DATA_STREAM;
pDemuxInfo->pbPacket = (pDemuxInfo->pbData - 4);
}
else if( (pDemuxInfo->ulStartCode >= MPEG_AUDIO2_PACKET_START_CODE_BEGIN) &&
(pDemuxInfo->ulStartCode <= MPEG_AUDIO2_PACKET_START_CODE_END) )
{
pDemuxInfo->ulDemuxState = DATA_STREAM;
pDemuxInfo->pbPacket = (pDemuxInfo->pbData - 4);
}
else if( (pDemuxInfo->ulStartCode >= MPEG_VIDEO_PACKET_START_CODE_BEGIN) &&
(pDemuxInfo->ulStartCode <= MPEG_VIDEO_PACKET_START_CODE_END) )
{
pDemuxInfo->ulDemuxState = DATA_STREAM;
pDemuxInfo->pbPacket = (pDemuxInfo->pbData - 4);
}
else if(pDemuxInfo->ulStartCode == MPEG_VIDEO_VC1_PACKET_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -