📄 mpginfo.cpp
字号:
/*****************************************************************************
******************************************************************************
** **
** Copyright (c) 2002 Videon Central, Inc. **
** All rights reserved. **
** **
** The computer program contained herein contains proprietary information **
** which is the property of Videon Central, Inc. The program may be used **
** and/or copied only with the written permission of Videon Central, Inc. **
** or in accordance with the terms and conditions stipulated in the **
** agreement/contract under which the programs have been supplied. **
** **
******************************************************************************
*****************************************************************************/
/**
* @file mpginfo.cpp
*
* Mpeg parsing utility routines
*
* $Id: mpginfo.cpp,v 1.7 2006/10/25 20:09:19 rbehe Exp $
*/
#include "vdvd_types.h"
#include "osapi.h"
#include "mpgstruct.h"
#include "mpginfo.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
#define swap16(x) (((x & 0x00ff) << 8) | ((x & 0xff00) >> 8))
ULONG MpgShowStart ( PVOID pData )
{
ULONG dwTemp;
BYTE *pbData = (BYTE *) pData;
#if 1
dwTemp = ((((ULONG)pbData[3])) & 0x000000ff);
dwTemp |= ((((ULONG)pbData[2]) << 8) & 0x0000ff00);
dwTemp |= ((((ULONG)pbData[1]) << 16) & 0x00ff0000);
dwTemp |= ((((ULONG)pbData[0]) << 24) & 0xff000000);
#else
dwTemp = ((ULONG)*pbData++ << 24);
dwTemp |= ((ULONG)*pbData++ << 16);
dwTemp |= ((ULONG)*pbData++ << 8);
dwTemp |= ((ULONG)*pbData++);
#endif
return dwTemp;
}
PVOID MpgSkipStart ( PVOID pData )
{
BYTE *pbData = (BYTE *) pData;
return (PVOID) (pbData+4);
}
PVOID MpgSkipPacket( ULONG dwStartCode, PVOID pData )
{
ULONG dwTemp;
BYTE bLength;
BYTE *pbData = (BYTE *) pData;
switch ( dwStartCode )
{
case MPEG_PACK_HEADER_START_CODE:
bLength = MpgGetPackStuffingLength ( pbData );
pbData += sizeof ( MPG_PACK_HDR );
pbData += bLength;
break;
case MPEG_SYSTEM_HEADER_START_CODE:
pbData += 4; // Skip Start Code
dwTemp = ((SHORT)*pbData++) << 8;
dwTemp |= *pbData++;
pbData += dwTemp;
while ( *pbData & 0x80 )
{
pbData += 3;
}
break;
// case MPEG_SEQUENCE_END_CODE:
// break;
case MPEG_PRIVATE_STREAM_1_START_CODE:
default:
pbData += 4; // Skip Start Code
dwTemp = ((SHORT)*pbData++) << 8;
dwTemp |= *pbData++;
pbData += dwTemp;
break;
}
return (PVOID) pbData;
}
PVOID MpgReadPack ( PMPG_PACK_HDR pmpgPack, PVOID pData )
{
BYTE *pbData = (BYTE *) pData;
BYTE *pbPack = (BYTE *) pmpgPack;
ULONG i;
for ( i = 0; i < sizeof ( MPG_PACK_HDR ); i++ )
{
*pbPack++ = *pbData++;
}
pbData += pmpgPack->bStuffingLength;
return (PVOID) pbData;
}
PVOID MpgReadGop ( PMPG_GOP_HDR pmpgGop, PVOID pData)
{
BYTE *pbData = (BYTE *) pData;
BYTE *pbGop = ((BYTE *) pmpgGop)+4;
ULONG i;
pmpgGop->dwStartCode = ((ULONG)*pbData++ << 24);
pmpgGop->dwStartCode |= ((ULONG)*pbData++ << 16);
pmpgGop->dwStartCode |= ((ULONG)*pbData++ << 8);
pmpgGop->dwStartCode |= ((ULONG)*pbData++);
i = sizeof ( MPG_GOP_HDR );
// For a ULONG bit field record from an MPEG stream
// we have to do a byte swap ( ie the 3-i on assignment )
for ( i = 0; i < sizeof ( MPG_GOP_HDR ) - 4; i++ )
{
*(pbGop+3-i) = *pbData++;
}
return (PVOID) pbData;
}
PVOID MpgReadPESHdr ( PMPG_PES_HDR pmpgPES, PVOID pData)
{
USHORT i;
BYTE *pbData = (BYTE *) pData;
BYTE *pbPES = ((BYTE *) pmpgPES) + 4 + 2;
// +sizeof(pmpgPES->dwStartCode)
// +sizeof(pmpgPES->wLength);
pmpgPES->dwStartCode = ((ULONG)*pbData++ << 24);
pmpgPES->dwStartCode |= ((ULONG)*pbData++ << 16);
pmpgPES->dwStartCode |= ((ULONG)*pbData++ << 8);
pmpgPES->dwStartCode |= ((ULONG)*pbData++);
pmpgPES->wLength = ((SHORT)*pbData++ << 8);
pmpgPES->wLength |= ((SHORT)*pbData++);
switch ( pmpgPES->dwStartCode )
{
case MPEG_PRIVATE_STREAM_2_START_CODE:
case MPEG_PADDING_STREAM_START_CODE:
break;
default:
for ( i = 0; i < sizeof ( MPG_PES_HDR ) -
//(sizeof(pmpgPES->dwStartCode)+sizeof(pmpgPES->wLength));
(4+2); i++ )
{
*(pbPES+i) = *pbData++;
}
// Skip filler
pbData += pmpgPES->bPES_header_data_length;
break;
}
return (PVOID) pbData;
}
ULONG MpgGetPESPTS32 ( BYTE *pbData )
{
MPG_PES_HDR mpgPES;
PMPG_PACKET_PTS pmpgPTS;
ULONG dwPTS;
MpgReadPESHdr ( &mpgPES, pbData );
if ( mpgPES.bPTSDTSFlags & MPG_PES_PTS_FLAG )
{
/*
DbgPrint(( "Raw PTS %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ",
*(pbData+sizeof(MPG_PES_HDR)-3),
*(pbData+sizeof(MPG_PES_HDR)-2),
*(pbData+sizeof(MPG_PES_HDR)-1),
*(pbData+sizeof(MPG_PES_HDR)+0),
*(pbData+sizeof(MPG_PES_HDR)+1),
*(pbData+sizeof(MPG_PES_HDR)+2),
*(pbData+sizeof(MPG_PES_HDR)+3),
*(pbData+sizeof(MPG_PES_HDR)+4),
*(pbData+sizeof(MPG_PES_HDR)+5),
*(pbData+sizeof(MPG_PES_HDR)+6) ));
*/
pmpgPTS = (PMPG_PACKET_PTS)
( pbData + sizeof ( MPG_PES_HDR ) );
dwPTS = pmpgPTS->bPTS32_30 << 30;
dwPTS |= pmpgPTS->bPTS29_22 << 22;
dwPTS |= pmpgPTS->bPTS21_15 << 15;
dwPTS |= pmpgPTS->bPTS14_7 << 7;
dwPTS |= pmpgPTS->bPTS6_0;
return dwPTS;
}
else
{
dwPTS = 0xFFFFFFFF;
}
return dwPTS;
}
ULONG MpgGetPESDTS32 ( BYTE *pbData )
{
MPG_PES_HDR mpgPES;
PMPG_PACKET_DTS pmpgDTS;
ULONG dwDTS;
MpgReadPESHdr ( &mpgPES, pbData );
if ( mpgPES.bPTSDTSFlags & MPG_PES_DTS_FLAG )
{
pmpgDTS = (PMPG_PACKET_DTS)
( pbData + sizeof ( MPG_PES_HDR ) + sizeof ( MPG_PACKET_PTS ) );
dwDTS = pmpgDTS->bDTS32_30 << 30;
dwDTS |= pmpgDTS->bDTS29_22 << 22;
dwDTS |= pmpgDTS->bDTS21_15 << 15;
dwDTS |= pmpgDTS->bDTS14_7 << 7;
dwDTS |= pmpgDTS->bDTS6_0;
return dwDTS;
}
else
{
dwDTS = 0xFFFFFFFF;
}
return dwDTS;
}
ULONG MpgGetPackSCR32 ( BYTE *pbData )
{
PMPG_PACK_HDR pmpgPack;
ULONG dwSCR;
// MpgReadPESHdr ( &mpgPES, pbData );
pmpgPack = (PMPG_PACK_HDR) pbData;
dwSCR = pmpgPack->bSCR32_30 << 30;
dwSCR |= pmpgPack->bSCR29_28 << 28;
dwSCR |= pmpgPack->bSCR27_20 << 20;
dwSCR |= pmpgPack->bSCR19_15 << 15;
dwSCR |= pmpgPack->bSCR14_13 << 13;
dwSCR |= pmpgPack->bSCR12_5 << 5;
dwSCR |= pmpgPack->bSCR4_0;
return dwSCR;
}
PVOID MpgReadSeqHdr ( PMPG_SEQ_HDR pmpgSEQ, PVOID pData)
{
BYTE *pbData = (BYTE *) pData;
BYTE *pbSEQ = ((BYTE *) pmpgSEQ)+sizeof ( pmpgSEQ->dwStartCode );
int i;
pmpgSEQ->dwStartCode = ((ULONG)*pbData++ << 24);
pmpgSEQ->dwStartCode |= ((ULONG)*pbData++ << 16);
pmpgSEQ->dwStartCode |= ((ULONG)*pbData++ << 8);
pmpgSEQ->dwStartCode |= ((ULONG)*pbData++);
for ( i = 0; i < 4; i++ )
{
*(pbSEQ+3-i) = *pbData++;
}
pbSEQ += 4;
for ( i = 0; i < 4; i++ )
{
*(pbSEQ+3-i) = *pbData++;
}
return (PVOID) pbData;
}
PVOID MpgReadExtSeqHdr ( PMPG_EXT_SEQ_HDR pmpgExtSEQ, PVOID pData)
{
BYTE *pbData = (BYTE *) pData;
BYTE *pbExtSEQ = ((BYTE *) pmpgExtSEQ)+sizeof ( pmpgExtSEQ->dwStartCode );
int i;
pmpgExtSEQ->dwStartCode = ((ULONG)*pbData++ << 24);
pmpgExtSEQ->dwStartCode |= ((ULONG)*pbData++ << 16);
pmpgExtSEQ->dwStartCode |= ((ULONG)*pbData++ << 8);
pmpgExtSEQ->dwStartCode |= ((ULONG)*pbData++);
for ( i = 0; i < 4; i++ )
{
*(pbExtSEQ+3-i) = *pbData++;
}
pbExtSEQ += 4;
for ( i = 0; i < 2; i++ )
{
*(pbExtSEQ+i) = *pbData++;
}
return (PVOID) pbData;
}
PVOID MpgFindStart ( PVOID pData, PVOID pBoundary )
{
BYTE *pbData = (BYTE *) pData;
if ( pbData > ((BYTE *)pBoundary-4) )
{
return pBoundary;
}
while ( (*pbData != 0x00) ||
(*(pbData+1) != 0x00) ||
(*(pbData+2) != 0x01) )
{
pbData++;
if ( pbData > ((BYTE *)pBoundary-4) )
{
break;
}
}
return (PVOID) pbData;
}
BOOLEAN MpgIsPes ( ULONG dwStartCode )
{
switch ( dwStartCode )
{
case MPEG_PACK_HEADER_START_CODE:
case MPEG_SYSTEM_HEADER_START_CODE:
case MPEG_PRIVATE_STREAM_1_START_CODE:
case MPEG_PRIVATE_STREAM_2_START_CODE:
case VIDEO_ELEMENTARY_STREAM:
case AUDIO_ELEMENTARY_STREAM:
case MPEG_PADDING_STREAM_START_CODE:
return TRUE;
break;
default:
return FALSE;
break;
}
return FALSE;
}
#ifdef USE_PUT_PES
SHORT MpgPutPes ( BYTE *pVideoPacket, SHORT wLength, BYTE *pVideoStorage, SHORT *pwCurrent, SHORT *pwUsed, SHORT wSize )
{
SHORT wMoveLen;
SHORT wUsedLen;
SHORT wLocalUsed = *pwUsed;
SHORT wLocalCurrent = *pwCurrent;
SHORT wAvailable;
if ( wLocalCurrent > 0 )
{
wMoveLen = wLocalUsed - wLocalCurrent;
memcpy( pVideoStorage, pVideoStorage+wLocalCurrent, wMoveLen );
wLocalUsed -= wLocalCurrent;
wLocalCurrent = 0;
}
wAvailable = wSize - wLocalUsed;
if ( wLength > wAvailable )
{
wUsedLen = wAvailable;
}
else
{
wUsedLen = wLength;
}
memcpy( pVideoStorage+wLocalUsed, pVideoPacket, wUsedLen );
*pwCurrent = 0;
*pwUsed = wUsedLen+wLocalUsed;
return wUsedLen;
}
#endif
BYTE *MpgFindStartCode ( BYTE *pBuffer, SHORT wLength, ULONG dwStartCode )
{
ULONG dwFoundCode = 0x00000000;
BYTE *pLocalBuffer = pBuffer;
BYTE *pReturn = NULL;
while ( dwFoundCode != dwStartCode )
{
pLocalBuffer = (BYTE *) MpgFindStart ( (PVOID) pLocalBuffer, (PVOID) (pBuffer+wLength) );
if ( pLocalBuffer > (pBuffer+wLength)-4 )
{
return pBuffer;
}
else
{
pReturn = pLocalBuffer;
dwFoundCode = ((ULONG)*pLocalBuffer++ << 24);
dwFoundCode |= ((ULONG)*pLocalBuffer++ << 16);
dwFoundCode |= ((ULONG)*pLocalBuffer++ << 8);
dwFoundCode |= ((ULONG)*pLocalBuffer++);
}
}
return pReturn;
}
ULONG MpgShowSyncCode ( PVOID pData )
{
ULONG dwHold = 0;
ULONG dwI = 0;
BYTE *pbData = (BYTE *) pData;
for ( dwI = 0; dwI < 4; dwI++ )
{
dwHold = dwHold << 8;
dwHold |= (ULONG)*(pbData+dwI);
}
return dwHold;
}
BYTE MpgGetPackStuffingLength ( BYTE *pbData )
{
PMPG_PACK_HDR pmpgPack;
pmpgPack = (PMPG_PACK_HDR) pbData;
return pmpgPack->bStuffingLength;
}
void MpgConvertTransportHeader ( BYTE *pmpgTrans )
{
#ifdef MPG_DO_SWAP
BYTE bData = *(pmpgTrans+1);
*(pmpgTrans+1) = *(pmpgTrans+2);
*(pmpgTrans+2) = bData;
#endif
}
void MpgConvertPSIHeader ( BYTE *pmpgPsi )
{
BYTE bData = *(pmpgPsi+1);
*(pmpgPsi+1) = *(pmpgPsi+2);
*(pmpgPsi+2) = bData;
}
void MpgConvertPATHeader ( BYTE *pmpgPat )
{
BYTE bData = *(pmpgPat+0);
*(pmpgPat+0) = *(pmpgPat+1);
*(pmpgPat+1) = bData;
}
void MpgConvertPASNumber ( BYTE *pmpgPas )
{
BYTE bData = *(pmpgPas+0);
*(pmpgPas+0) = *(pmpgPas+1);
*(pmpgPas+1) = bData;
bData = *(pmpgPas+2);
*(pmpgPas+2) = *(pmpgPas+3);
*(pmpgPas+3) = bData;
}
void MpgConvertPMTHeader ( BYTE *pmpgPmt )
{
BYTE bData = *(pmpgPmt+0);
*(pmpgPmt+0) = *(pmpgPmt+1);
*(pmpgPmt+1) = bData;
bData = *(pmpgPmt+5);
*(pmpgPmt+5) = *(pmpgPmt+6);
*(pmpgPmt+6) = bData;
bData = *(pmpgPmt+7);
*(pmpgPmt+7) = *(pmpgPmt+8);
*(pmpgPmt+8) = bData;
}
void MpgConvertPidDescriptor ( BYTE *pmpgPid )
{
BYTE bData = *(pmpgPid+1);
*(pmpgPid+1) = *(pmpgPid+2);
*(pmpgPid+2) = bData;
bData = *(pmpgPid+3);
*(pmpgPid+3) = *(pmpgPid+4);
*(pmpgPid+4) = bData;
}
/************************************************************************/
/************************************************************************/
/** **/
/************************************************************************/
/************************************************************************/
BYTE * MpgGetPayload( BYTE *pmpgData )
{
PMPG_TRANSPORT_HDR pThdr;
BYTE *pTemp;
BYTE bAdaptLen;
pThdr = (PMPG_TRANSPORT_HDR)(pmpgData);
pTemp = pmpgData;
if( pThdr->bAdaptationFieldControl == 0x01 )
{
pTemp += 4;
}
else if( pThdr->bAdaptationFieldControl == 0x03 )
{
bAdaptLen = pmpgData[4];
pTemp += 4 + 1 + (ULONG)bAdaptLen;
}
else if( pThdr->bAdaptationFieldControl == 0x02 )
{
pTemp += MPG_TRANSPORT_SIZE;
}
else
{
DbgPrint(( "MpgGetPayload:A Field = %d\n", (int)pThdr->bAdaptationFieldControl ));
}
return( pTemp );
} /* end MpgGetPayload() */
ULONG MpgGetPCR ( BYTE *pmpgPCR )
{
PMPG_ADAPTATION_PCR pmpgPcr = (PMPG_ADAPTATION_PCR) pmpgPCR;
ULONG dwPCR;
dwPCR = swap16(pmpgPcr->wProgramClockReferenceBase1) << 17 |
swap16(pmpgPcr->wProgramClockReferenceBase2) << 1 | pmpgPcr->wProgramClockReferenceBase3;
return (dwPCR);
}
PVOID MpgReadPS1Hdr ( PMPG_PS1_HDR pmpgPS1, PVOID pData)
{
USHORT i;
BYTE *pbData = (BYTE *) pData;
BYTE *pbPS1 = ((BYTE *) pmpgPS1) + sizeof(pmpgPS1->bSubStreamId) + sizeof(pmpgPS1->bNumberOfFrameHeaders)
+ sizeof(pmpgPS1->wFirstAccessUnitPointer);
pmpgPS1->bSubStreamId = *pbData++;
pmpgPS1->bNumberOfFrameHeaders = *pbData++;
pmpgPS1->wFirstAccessUnitPointer = (*pbData++ << 8);
pmpgPS1->wFirstAccessUnitPointer |= (*pbData++);
if ( PCM_SUB_STREAM_ID ( pmpgPS1->bSubStreamId ) )
{
for ( i = 0; i < sizeof ( MPG_PS1_HDR ) - (pbPS1 - (BYTE *)pmpgPS1); i++)
{
*(pbPS1+i) = *pbData++;
}
}
return (PVOID) pbData;
}
PVOID MpgReadAC3Hdrs ( PAC3_SYNC_HDR pAC3Sync, PAC3_BSI_HDR pAC3Bsi, PVOID pData)
{
BYTE *pbData = (BYTE *)pData;
BYTE *pbAc3Sync = ((BYTE *)pAC3Sync) + sizeof(pAC3Sync->wSync) + sizeof(pAC3Sync->wCrc1);
BYTE *pbAc3Bsi = ((BYTE *)pAC3Bsi);
pAC3Sync->wSync = (*pbData++ << 8);
pAC3Sync->wSync |= (*pbData++);
pAC3Sync->wCrc1 = (*pbData++ << 8);
pAC3Sync->wCrc1 |= (*pbData++);
*(pbAc3Sync) = *pbData++;
*(pbAc3Bsi+0) = *pbData++;
*(pbAc3Bsi+1) = *pbData++;
return (PVOID) pbData;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -