📄 mmutils.cpp
字号:
INT res_stuff = *(pBuffer + dwBufferIndex++) & 0x7; // Pack stuffing length,
dwBufferIndex += res_stuff;
dwSyncCode = 0;
}
else if (dwSyncCode == SYSTEM_START_CODE)
{
dwBufferIndex += 8;
while (TRUE)
{
if (dwBufferIndex >= lLength)
break;
byte = *(pBuffer + dwBufferIndex);
if ((byte >> 7) == 1) // first bit is 1, skip 3 bytes
dwBufferIndex += 3; // Stream id, buffer bound scale and bufer size bound (3 bytes).
else
break;
}
dwSyncCode = 0;
}
else if ((dwSyncCode == PADDING_STREAM) || (dwSyncCode == PRIVATE_STREAM_2) ||
(dwSyncCode == PROGRAM_STREAM_MAP))
{
if (dwBufferIndex >= lLength)
break;
wPacketLength = *(pBuffer + dwBufferIndex++);
if (dwBufferIndex >= lLength)
break;
wPacketLength = (wPacketLength << 8) | *(pBuffer + dwBufferIndex++);
dwBufferIndex += wPacketLength;
dwSyncCode = 0;
}
else if ((dwSyncCode & 0xF0FFFFFF) == VIDEO_STREAM)
{
if (dwBufferIndex >= lLength)
break;
wPacketLength = *(pBuffer + dwBufferIndex++);
if (dwBufferIndex >= lLength)
break;
wPacketLength = (wPacketLength << 8) | *(pBuffer + dwBufferIndex++);
dwBufferIndex += wPacketLength;
dwSyncCode = 0;
}
// PARSE THE AUDIO PES PACKET TO GET THE PAYLOAD.
else if (((dwSyncCode & 0xF0FFFFFF) == AUDIO_STREAM) || (dwSyncCode == AC3_PCM_DTS_STREAM))
{
if (dwBufferIndex + 2 >= lLength)
break;
wPacketLength = *(pBuffer + dwBufferIndex++);
wPacketLength = (wPacketLength << 8) | *(pBuffer + dwBufferIndex++);
// Scrambling control, priority, alignment, copyright and original bits.
dwBufferIndex++;
// PTS, DTS, ESCR, ESRate, DSM trick mode, additional copy info, CRC and extension flags.
dwBufferIndex++;
// Header Data Length
if (dwBufferIndex >= lLength)
break;
INT bHeaderDataLength = *(pBuffer + dwBufferIndex++);
dwBufferIndex += bHeaderDataLength;
// Found the PES payload. Start looking for the sync word of audio frame.
if ((dwSyncCode == AC3_PCM_DTS_STREAM) && (dwBufferIndex + 4 < lLength))
{
// Sub stream id: AC3 (10000***b), DTS (10001***b), PCM (10100***b), SUB (001*****b)
BYTE bSubstreamId = *(pBuffer + dwBufferIndex++);
if ((bSubstreamId >> 5) != SUB_SUBSTREAM_ID)
{
dwBufferIndex += 3; // number of frame headers and first access unit pointer
bHeaderDataLength += 3;
switch (bSubstreamId >> 3)
{
case AC3_SUBSTREAM_ID:
return GetAc3AudioFrequency(pBuffer + dwBufferIndex, lLength - dwBufferIndex);
case DTS_SUBSTREAM_ID:
return AUDIO_FREQ_48;
break;
case PCM_SUBSTREAM_ID:
dwBufferIndex++;
if (dwBufferIndex >= lLength)
break;
byte = *(pBuffer + dwBufferIndex++);
byte = (byte >> 4) & 0x3;
if (byte == 0)
{
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Sample rate: 48K"));
return AUDIO_FREQ_48;
}
else if (byte == 1)
{
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Sample rate: 96K"));
return AUDIO_FREQ_96;
}
else
{
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Sample rate: reserved, use 48Khz"));
return AUDIO_FREQ_48;
}
break;
}
}
dwBufferIndex += (wPacketLength - bHeaderDataLength);
}
else // Mpeg1 audio
{
while (dwBufferIndex + 4 < lLength)
{
INT wSyncWord = *(pBuffer + dwBufferIndex++);
wSyncWord = (wSyncWord << 8) | *(pBuffer + dwBufferIndex++);
if (((wSyncWord & 0xFFF0) == 0xFFF0) && ((wSyncWord & 0xF) == 0)) // Audio frame header syncword
{
BYTE byte = *(pBuffer + dwBufferIndex++);
INT bSamplingFreq = (byte >> 2) & 3;
INT bPaddingBit = (byte >> 1) & 1;
if (bPaddingBit == 1)
bSamplingFreq = 0;
if (bSamplingFreq == 0)
{
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Sample rate: 44.1K"));
return AUDIO_FREQ_441;
}
else if (bSamplingFreq == 0x01)
{
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Sample rate: 48K"));
return AUDIO_FREQ_48;
}
else if (bSamplingFreq == 0x2)
{
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Sample rate: 32K"));
return AUDIO_FREQ_32;
}
else
{
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Sample rate: reserved, use 44.1Khz"));
return AUDIO_FREQ_441;
}
}
}
}
dwSyncCode = 0;
}
}
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Unable to identify sample rate, set to 44.1K"));
return AUDIO_FREQ_441; // Make this a default.
}
/////////////////////////////////////////////////////////////////////////////
// Reverse every 2 bytes
void ReverseBytes(unsigned char *pBuffer, unsigned long dwLength)
{
DWORD dwIndex = 0;
BYTE temp = 0;
for (; dwIndex < dwLength;)
{
temp = *(pBuffer + dwIndex);
*(pBuffer + dwIndex) = *(pBuffer + dwIndex + 1);
*(pBuffer + dwIndex + 1) = temp;
dwIndex += 2;
}
}
////////////////////////////////////////////////////////////////////
/****f* MMDemux/GetAc3AudioFrequency
* USAGE
* DWORD GetAc3AudioFrequency(char *pFileName)
* DWORD GetAc3AudioFrequency(unsigned char* pBuffer, DWORD dwLength)
* DESCRIPTION
* Gets the audio sample rate of AC3
* PARAMETERS
* char* pFileName - File name
* RETURN VALUE
* Audio sample rate
/**********************************************************************/
DWORD GetAc3AudioFrequency(char *pFileName)
{
BYTE bBuffer[READ_BUFFERSIZE];
DWORD dwReadSize = 0;
FILE *pFile;
if ((pFile = fopen(pFileName, "rb")) == NULL)
{
printf("Unable to open file!\n");
return FALSE;
}
dwReadSize = fread(bBuffer, sizeof(char), READ_BUFFERSIZE, pFile);
fclose(pFile);
return GetAc3AudioFrequency(bBuffer, dwReadSize);
}
////////////////////////////////////////////////////////////////////
DWORD GetAc3AudioFrequency(unsigned char* pBuffer, DWORD dwLength)
{
DWORD dwBufferIndex = 0;
BYTE byte = 0;
if (IsAc3Reverse(pBuffer, dwLength))
ReverseBytes(pBuffer, dwLength);
while ((dwBufferIndex + 4) < dwLength)
{
byte = *(pBuffer + dwBufferIndex++);
if (byte == 0x0B)
{
byte = *(pBuffer + dwBufferIndex++);
if (byte == 0x77)
{
INT crc1 = *(pBuffer + dwBufferIndex++);
crc1 = (crc1 << 8) + *(pBuffer + dwBufferIndex++);
byte = *(pBuffer + dwBufferIndex++);
INT bSamplingFreq = (byte >> 6) & 0x3;
INT bFrameSize = byte & 0x3F;
if (bSamplingFreq == 1)
{
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Sample rate: 44.1K"));
return AUDIO_FREQ_441;
}
else if (bSamplingFreq == 0)
{
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Sample rate: 48K"));
return AUDIO_FREQ_48;
}
else if (bSamplingFreq == 2)
{
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Sample rate: 32K"));
return AUDIO_FREQ_32;
}
else
{
MmDebugLogfile ((MmDebugLevelLog|MmDebugLevelTrace, "Sample rate: reserved, use 48KHz"));
return AUDIO_FREQ_48;
}
}
}
}
return AUDIO_FREQ_441; // make this default
}
////////////////////////////////////////////////////////////////////
INT GetAc3AudioFrameSize(const unsigned char* pBuffer, unsigned long dwLength)
{
DWORD dwBufferIndex = 0;
BYTE bSyncCode = 0;
INT iFrameSize = 0;
BYTE byte = 0;
while (dwBufferIndex + 6 < dwLength)
{
bSyncCode = *(pBuffer + dwBufferIndex++);
if (bSyncCode == 0x0B)
{
bSyncCode = *(pBuffer + dwBufferIndex++);
if (bSyncCode == 0x77)
{
dwBufferIndex += 2;
// Get frame syncinfo
byte = *(pBuffer + dwBufferIndex++);
INT bSampleRate = (byte >> 6) & 0x3;
INT bFrameSizeCode = byte & 0x3F;
if (bFrameSizeCode >= 38)
continue;
if (bSampleRate == 0)
iFrameSize = Ac3FrameSize[bFrameSizeCode].SR48;
else if (bSampleRate == 1)
iFrameSize = Ac3FrameSize[bFrameSizeCode].SR441;
else if (bSampleRate == 2)
iFrameSize = Ac3FrameSize[bFrameSizeCode].SR32;
if (iFrameSize > 0)
break;
}
}
}
return iFrameSize * 2;
}
////////////////////////////////////////////////////////////////////
INT GetAc3AudioFrameSize(char* pFileName)
{
BYTE bBuffer[READ_BUFFERSIZE];
LONG lReadSize = 0;
FILE *pfile;
if ((pfile = fopen(pFileName, "rb")) == NULL)
{
printf("Unable to open file!\n");
return 0;
}
lReadSize = fread(bBuffer, sizeof(char), READ_BUFFERSIZE, pfile);
fclose(pfile);
return GetAc3AudioFrameSize(bBuffer, lReadSize);
}
////////////////////////////////////////////////////////////////////
/****f* MMDemux/IsAc3Reverse
* USAGE
* BOOL IsAc3Reverse(char* pFile)
* BOOL IsAc3Reverse(const BYTE* pBuffer, DWORD dwBufferSearchSize)
* DESCRIPTION
* Determines whether this is an audio AC3 reverse stream.
* PARAMETERS
* const BYTE *pBuffer - a pointer to the data buffer to search.
* DWORD dwBufferSearchSize - size of the search buffer.
* RETURN VALUE
* TRUE if it is reverse; otherwise, FALSE.
/**********************************************************************/
BOOL IsAc3Reverse(char* pFile)
{
BYTE bBuffer[READ_BUFFERSIZE];
LONG lReadSize = 0;
FILE *pPlayfile;
if ((pPlayfile = fopen(pFile, "rb")) == NULL)
{
printf("Unable to open file!\n");
return FALSE;
}
lReadSize = fread(bBuffer, sizeof(char), READ_BUFFERSIZE, pPlayfile);
fclose(pPlayfile);
return IsAc3Reverse(bBuffer, lReadSize);
}
////////////////////////////////////////////////////////////////////
BOOL IsAc3Reverse(const BYTE* pBuffer, DWORD dwBufferSearchSize)
{
DWORD dwBufferIndex = 0;
BYTE bSyncCode = 0;
INT iFrameSize = 0;
BOOL bAc3Reverse = FALSE;
int iCounter = 0;
char szBuf[4];
while (dwBufferIndex + 6 < dwBufferSearchSize)
{
bSyncCode = *(pBuffer + dwBufferIndex++);
if (bSyncCode == 0x77)
{
bSyncCode = *(pBuffer + dwBufferIndex++);
if (bSyncCode == 0x0B)
{
// Get frame syncinfo
memcpy(szBuf, pBuffer + dwBufferIndex, 4);
ReverseBytes((unsigned char*)szBuf, 4);
INT bSampleRate = (szBuf[2] >> 6) & 0x3;
INT bFrameSizeCode = szBuf[2] & 0x3F;
if (bFrameSizeCode >= 38)
return FALSE;
if (bSampleRate == 0)
iFrameSize = Ac3FrameSize[bFrameSizeCode].SR48;
else if (bSampleRate == 1)
iFrameSize = Ac3FrameSize[bFrameSizeCode].SR441;
else if (bSampleRate == 2)
iFrameSize = Ac3FrameSize[bFrameSizeCode].SR32;
// Advance to next syncword
if (iFrameSize > 0)
{
dwBufferIndex += (iFrameSize * 2 - 2);
bAc3Reverse = TRUE;
iCounter++;
}
iFrameSize = 0;
}
// Found syncword but unsuccessfull to try next syncword.
else if (bAc3Reverse)
return FALSE;
}
else if (bAc3Reverse)
return FALSE;
}
if (iCounter >= 2)
return bAc3Reverse;
else
return FALSE;
}
////////////////////////////////////////////////////////////////////
/****f* MMDemux/GetTSProgramCounter
* USAGE
* int GetTSProgramCounter(char* pFile)
* int GetTSProgramCounter(const BYTE* pBuffer, DWORD dwLength)
* DESCRIPTION
* Determines the number of programs in a transport stream.
* PARAMETERS
* const BYTE *pSearchBuffer - a pointer to the data buffer to search.
* DWORD dwSearchBufferSize - size of the search buffer.
* RETURN VALUE
* Number of the programs.
/**********************************************************************/
INT GetTSProgramCounter(char* pFile)
{
BYTE bBuffer[READ_BUFFERSIZE];
DWORD dwReadSize = 0;
FILE *pPlayfile;
if ((pPlayfile = fopen(pFile, "rb")) == NULL)
{
MmDebugLogfile((MmDebugLevelTrace, "Unable to open file!"));
return 0;
}
dwReadSize = fread(bBuffer, sizeof(char), READ_BUFFERSIZE, pPlayfile);
fclose(pPlayfile);
int counter = 0;
counter = GetTSProgramCounter(bBuffer, dwReadSize);
if (counter == 0)
counter = 1;
return counter;
}
////////////////////////////////////////////////////////////////////
INT GetTSProgramCounter(const BYTE* pBuffer, DWORD dwLength)
{
BYTE bCode = 0;
DWORD dwBufferIndex = 0;
int iCounter = 0;
while (dwBufferIndex < dwLength)
{
bCode = *(pBuffer + dwBufferIndex++);
if (bCode == M2T_SYNC_BYTE)
{
BYTE byte = 0;
WORD wLength = 0;
// Number of bytes have moved so far in the TS packet after the sync byte.
INT wBytesAdvanced = 0;
if (dwBufferIndex >= dwLength)
break;
byte = *(pBuffer + dwBufferIndex++);
INT bPayloadStart = (byte & 0x40) >> 6; // Bit 6
INT wPid = byte & 0x1F; // Bits 4-0
if (dwBufferIndex+1 >= dwLength)
break;
wPid = (wPid << 8) | *(pBuffer + dwBufferIndex++);
byte = *(pBuffer + dwBufferIndex++);
INT bScrambling = (byte & 0xC0) >> 6; // Bit 7 & 6
INT bAdaptFieldCtrl = (byte & 0x30) >> 4; // Bit 5 & 4
wBytesAdvanced += 3;
// Adaptation field presents
if ((bAdaptFieldCtrl == 0x2) || (bAdaptFieldCtrl == 0x3))
{
INT bAdaptFieldLength = 0;
bAdaptFieldLength = *(pBuffer + dwBufferIndex++);
if (bAdaptFieldCtrl == 0x2 && bAdaptFieldLength != 183)
continue;
else if ((bAdaptFieldCtrl == 0x3)
&&
(bAdaptFieldLength < 0)
&&
(bAdaptFieldLength > 182)
)
continue;
dwBufferIndex += bAdaptFieldLength;
wBytesAdvanced += bAdaptFieldLength;
}
// Payload presents
if ((bAdaptFieldCtrl == 0x1) || (bAdaptFieldCtrl == 0x3))
{
if (wPid == 0x1FFF) // Null packet
{
// Invalid TS packet?
if ((bPayloadStart != 0) || (bAdaptFieldCtrl != 1) || (bScrambling != 0))
continue;
// Advance to first byte of next packet.
dwBufferIndex += (187 - wBytesAdvanced);
continue;
}
// Either PES packet or PSI data presents
else if (bPayloadStart == 1)
{
if (dwBufferIndex >= dwLength)
break;
BYTE bPointerField = *(pBuffer + dwBufferIndex++);
if (bPointerField > (187 - wBytesAdvanced))
continue;
// Move the buffer index to the first byte of the section while checking
// for end of buffer.
dwBufferIndex += bPointerField;
if (dwBufferIndex >= dwLength)
break;
BYTE bTableId = *(pBuffer + dwBufferIndex++);
if ((bTableId == 0) || (bTableId == 1) || (bTableId == 2) ||
(bTableId >= 0x40 && bTableId <= 0xFE))
{
wBytesAdvanced += (bPointerField + 2);
switch (bTableId)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -