/* Parse system header
Parameters :
pbData - pointer to data containing the system header
cbData - length of data
Returns :
Number of bytes processed (0 if the header doesn't fit
in the data or 4 if the header is invalid)
*/
LONG ParseSystemHeader(const BYTE * pbData, DWORD cbData)
{
BOOL bHasAudio = FALSE;
BOOL bHasVideo = FALSE;
ASSERT(cbData >= 4);
ASSERT(*(UNALIGNED DWORD *)pbData == DWORD_SWAP(SYSTEM_HEADER_START_CODE));
/* Checkt the length */
if (cbData < 6) {
return 0;
}
DWORD dwLen = 6 + pbData[5] + (pbData[4] << 8);
if (dwLen < SYSTEM_HEADER_BASIC_LENGTH) {
DbgLog((LOG_ERROR, 1, TEXT("Invalid System Header length")));
return 4;
}
if (cbData < dwLen) {
return 0;
}
/* Check the marker bits */
if (0 == (pbData[6] & 0x80) ||
0 == (pbData[8] & 0x01) ||
0 == (pbData[10] & 0x20)) {
DbgLog((LOG_ERROR, 1, TEXT("Invalid System Header Marker bits")));
return 4;
}
/* Parse the 'buffer bounds and scale' list */
const BYTE * pbNext = pbData + SYSTEM_HEADER_BASIC_LENGTH;
DWORD cbLeft = dwLen - SYSTEM_HEADER_BASIC_LENGTH;
for ( ; cbLeft >= 3; cbLeft -= 3, pbNext += 3) {
if (pbNext[0] == AUDIO_GLOBAL) {
bHasAudio = TRUE;
} else
if (pbNext[0] == VIDEO_GLOBAL) {
bHasVideo = TRUE;
} else {
if (pbNext[0] < PROGRAM_STREAM_MAP) {
DbgLog((LOG_ERROR, 1, TEXT("Invalid stream id in system header")));
return 4;
}
if (IsVideoStreamId(pbNext[0])) {
bHasVideo = TRUE;
} else
if (IsAudioStreamId(pbNext[0])) {
bHasAudio = TRUE;
}
}
}
if (cbLeft != 0) {
DbgLog((LOG_ERROR, 1, TEXT("Invalid system header length")));
return 4;
}
DbgLog((LOG_TRACE, 4, TEXT("System Header %s, %s"),
bHasAudio ? TEXT("audio") : TEXT("No audio"),
bHasVideo ? TEXT("video") : TEXT("No video")));
return dwLen;
}