⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmutils.cpp

📁 神龙卡 SDK_84xx_DShow_145_02.zip 这个是 windows 上二个是linux
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include "pch.h"
#include "mmdebug.h"
#include "mmutils.h"


#ifndef READ_BUFFERSIZE
#define READ_BUFFERSIZE 0x40000  // 256KB
//#define READ_BUFFERSIZE 0x80000  // 512KB
//#define READ_BUFFERSIZE 0x100000	// 1MB
#endif


////////////////////////////////////////////////////////////////////

void CheckSubStreamId(INT iSubStreamId, AudioSubtype* audioSubtype,
											MM_AUDIO_FORMAT* bAudioFormat)
{
	switch (iSubStreamId >> 3)
	{
		case AC3_SUBSTREAM_ID:
			if (!audioSubtype->bIsAc3)
			{
				audioSubtype->bIsAc3 = TRUE;
				MmDebugLogfile((MmDebugLevelTrace, "AUDIO_FORMAT_AC3"));
			}
			if (!audioSubtype->bIsDts && !audioSubtype->bIsPcm)
				*bAudioFormat = MM_MEDIASUBTYPE_DOLBY_AC3;
			break;
		case DTS_SUBSTREAM_ID:
			if (!audioSubtype->bIsDts)
			{
				audioSubtype->bIsDts = TRUE;
				MmDebugLogfile((MmDebugLevelTrace, "AUDIO_FORMAT_DTS"));
			}
			if (!audioSubtype->bIsAc3 && !audioSubtype->bIsPcm)
				*bAudioFormat = MM_MEDIASUBTYPE_DTS;
			break;
		case PCM_SUBSTREAM_ID:
			if (!audioSubtype->bIsPcm)
			{
				audioSubtype->bIsPcm = TRUE;
				MmDebugLogfile((MmDebugLevelTrace, "AUDIO_FORMAT_PCM"));
			}
			if (!audioSubtype->bIsAc3 && !audioSubtype->bIsDts)
				*bAudioFormat = MM_MEDIASUBTYPE_PCM;
			break;
		case SDDS_SUBSTREAM_ID:
			MmDebugLogfile((MmDebugLevelTrace, "AUDIOSUBTYPE_SDDS"));
			break;
	}
}

////////////////////////////////////////////////////////////////////
/****f* MMDemux/IdentifyAudioSubtype
 * USAGE
 *  MM_AUDIO_FORMAT IdentifyAudioSubtype(char *pSourceFile, AudioSubtype* audioSubtype,
 *    int iStreamType = FT_UNKNOWN)
 *  MM_AUDIO_FORMAT IdentifyAudioSubtype(unsigned char* pBuffer, unsigned long dwLength, 
 *    AudioSubtype* audioSubtype, int iStreamType = FT_UNKNOWN)
 * DESCRIPTION
 *  Identify the audio subtype of a file.
 * PARAMETERS
 *  char *pSourceFile - Pointer to the source file name
 *  AudioSubtype* audioSubtype - 
 * RETURN VALUE
 *  MM_MEDIASUBTYPE_MPEG1Payload if audio subtype is of type audio stream
 *    (for both mpeg1 and mpeg2).
 *  MM_MEDIASUBTYPE_DOLBY_AC3 if audio subtype is of Ac3 stream.
 *  MM_MEDIASUBTYPE_PCM if audio subtype is of PCM stream.
 *  MM_MEDIASUBTYPE_DTS if the stream contains both AC3 and DTS.
 * NOTES
 *  If using with COM Interface, MM_AUDIO_FORMAT has format as GUID.
 *  Else, MM_AUDIO_FORMAT has format as INT.
/**********************************************************************/
MM_AUDIO_FORMAT IdentifyAudioSubtype(char *pSourceFile, AudioSubtype* audioSubtype, 
												 int iStreamType)
{
	BYTE bBuffer[READ_BUFFERSIZE];
	DWORD dwReadSize = 0;
	INT i = 0;
	MM_AUDIO_FORMAT audio = MM_MEDIASUBTYPE_NULL;
	FILE *pPlayfile;

	if ((pPlayfile = fopen(pSourceFile, "rb")) == NULL)
	{
		printf("Unable to open file!\n");
		return MM_MEDIASUBTYPE_NULL;
	}

	dwReadSize = fread(bBuffer, sizeof(char), READ_BUFFERSIZE, pPlayfile);
	if (iStreamType == FT_UNKNOWN)
		iStreamType = IdentifyHeader(bBuffer, dwReadSize);

	audio = IdentifyAudioSubtype(bBuffer, dwReadSize, audioSubtype, iStreamType);	
	if (audio == MM_MEDIASUBTYPE_NULL)
	{
		for (i = 0; i < 3; i++)
		{
			dwReadSize = fread(bBuffer, sizeof(char), READ_BUFFERSIZE, pPlayfile);
			audio = IdentifyAudioSubtype(bBuffer, dwReadSize, audioSubtype, iStreamType);	
			if (audio != MM_MEDIASUBTYPE_NULL)
				break;
		}
	}
	fclose(pPlayfile);
	return audio;
}

////////////////////////////////////////////////////////////////////

MM_AUDIO_FORMAT IdentifyAudioSubtype(unsigned char* pBuffer, unsigned long dwLength, 
												 AudioSubtype* audioSubtype, int iStreamType)
{
	DWORD dwBufferIndex = 0;
	DWORD dwCode = 0;
	BYTE byte = 0;
	INT wPacketLength = 0;
	INT wHeaderDataLength = 0;
	MM_AUDIO_FORMAT bAudioFormat = MM_MEDIASUBTYPE_NULL;	

	if (iStreamType == FT_UNKNOWN)
		iStreamType = IdentifyHeader(pBuffer, dwLength);

	if (iStreamType == FT_AC3_AUDIO)
	{
		audioSubtype->bIsAc3 = TRUE;
		return MM_MEDIASUBTYPE_DOLBY_AC3;
	}

	if (iStreamType == FT_DTS_AUDIO)
	{
		audioSubtype->bIsDts = TRUE;
		return MM_MEDIASUBTYPE_DTS;
	}

	if (iStreamType == FT_MPEG2_TRANSPORT)
	{
		while (dwBufferIndex < dwLength)
		{
			byte = *(pBuffer + dwBufferIndex++);
			if (byte == M2T_SYNC_BYTE)
			{
				// Number of bytes have moved so far in the TS packet after the sync byte.
				INT wBytesAdvanced = 0;

				// Transport error indicator, payload unit start indicator, transport priority and PID
				dwBufferIndex += 2;
				// Transport scrambling control, adaptation field control, continuity counter				
				if (dwBufferIndex >= dwLength)
					break;
				byte = *(pBuffer + dwBufferIndex++);
				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 (dwBufferIndex + (187 - wBytesAdvanced) >= dwLength)
						break;
					DWORD nextTSIndex = dwBufferIndex + (187 - wBytesAdvanced);

					while (dwBufferIndex < nextTSIndex)
					{
						dwCode = (dwCode << 8) | *(pBuffer + dwBufferIndex++);
						if ((dwCode & 0xF0FFFFFF) == AUDIO_STREAM)
						{
							MmDebugLogfile((MmDebugLevelTrace, "AUDIO_FORMAT_MPEG1"));
							audioSubtype->bIsMpeg1 = TRUE;
							return MM_MEDIASUBTYPE_MPEG1Payload;
						}
						else if (dwCode == AC3_PCM_DTS_STREAM)
						{	
							// Assume it's AC3 for now.
							MmDebugLogfile((MmDebugLevelTrace, "AUDIO_FORMAT_AC3"));
							audioSubtype->bIsAc3 = TRUE;
							return MM_MEDIASUBTYPE_DOLBY_AC3;

							wPacketLength = *(pBuffer + dwBufferIndex++);
							wPacketLength = (wPacketLength << 8) | *(pBuffer + dwBufferIndex++);

							// Scrambling control, priority, alignment, copyright and original or copy bits.
							dwBufferIndex++;

							// PTS, DTS, ESCR, ESRate, DSM trick mode, additional copy info, CRC and
							// extension flags.
							dwBufferIndex++;
		
							// Get Header Data Length
							wHeaderDataLength = *(pBuffer + dwBufferIndex++);
							dwBufferIndex += wHeaderDataLength;

							// Sub stream id: AC3 (10000***b), DTS (10001***b), PCM (10100***b), SUB (001*****b),
							// SDDS (10010***b)
							if (dwBufferIndex >= dwLength)
								break;
							BYTE bSubStreamId = *(pBuffer + dwBufferIndex++);
							wHeaderDataLength++;
							if ((bSubStreamId >> 5) != SUB_SUBSTREAM_ID)
							{
								// Skip number of frame headers and first access unit pointer
								dwBufferIndex += 3;
								wHeaderDataLength += 3;
								CheckSubStreamId(bSubStreamId, audioSubtype, &bAudioFormat);
								if ((bSubStreamId >> 3) == PCM_SUBSTREAM_ID)
								{
									dwBufferIndex++;
									if (dwBufferIndex >= dwLength)
										break;
									byte = *(pBuffer + dwBufferIndex++);
									INT iQuantizationWordLength = (byte >> 6) & 0x3;
									INT iSampleRate = (byte >> 4) & 0x3;
									INT iNumAudioChannels = (byte & 0x7) + 1;
									audioSubtype->pcmAudio.iBitsPerSample = quantization_table[iQuantizationWordLength];
									audioSubtype->pcmAudio.iSampleRate = pcm_sample_rate_table[iSampleRate];
									audioSubtype->pcmAudio.iNumAudioChannels = iNumAudioChannels;
									dwBufferIndex++;
								}
							}
						}
					}
				}
			}
		}	
	}
	else   // Program stream
	{
		while (dwBufferIndex < dwLength)
		{
			dwCode = (dwCode << 8) | *(pBuffer + dwBufferIndex++);

			if (dwCode == PACK_START_CODE)
			{	
				dwBufferIndex += 9;   // SCR and Mux rate
				if (dwBufferIndex >= dwLength)
					break;
				INT res_stuff = *(pBuffer + dwBufferIndex++) & 0x7;  // Pack stuffing length,
				dwBufferIndex += res_stuff;
				dwCode = 0;
			}
			else if (dwCode == SYSTEM_START_CODE)
			{
				dwBufferIndex += 8;
				while (TRUE)
				{
					if (dwBufferIndex >= dwLength)
						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;
				}
				dwCode = 0;
			}
			else if ((dwCode == PADDING_STREAM) || (dwCode == PRIVATE_STREAM_2) ||
						(dwCode == PROGRAM_STREAM_MAP))
			{
				if (dwBufferIndex >= dwLength)
					break;
				wPacketLength = *(pBuffer + dwBufferIndex++);
				if (dwBufferIndex >= dwLength)
					break;
				wPacketLength = (wPacketLength << 8) | *(pBuffer + dwBufferIndex++);
				dwBufferIndex += wPacketLength;
				dwCode = 0;
			}
			else if ((dwCode & 0xF0FFFFFF) == VIDEO_STREAM)
			{
				if (dwBufferIndex >= dwLength)
					break;
				wPacketLength = *(pBuffer + dwBufferIndex++);
				if (dwBufferIndex >= dwLength)
					break;
				wPacketLength = (wPacketLength << 8) | *(pBuffer + dwBufferIndex++);
				dwBufferIndex += wPacketLength;
				dwCode = 0;
			}
			else if ((dwCode & 0xF0FFFFFF) == AUDIO_STREAM)
			{
				MmDebugLogfile((MmDebugLevelTrace, "AUDIO_FORMAT_MPEG1"));
				audioSubtype->bIsMpeg1 = TRUE;
				return MM_MEDIASUBTYPE_MPEG1Payload;
			}
			else if (dwCode == AC3_PCM_DTS_STREAM)
			{	
				if (dwBufferIndex + 2 >= dwLength)
					break;
				wPacketLength = *(pBuffer + dwBufferIndex++);
				wPacketLength = (wPacketLength << 8) | *(pBuffer + dwBufferIndex++);

				// Scrambling control, priority, alignment, copyright and original or copy bits.
				dwBufferIndex++;

				// PTS, DTS, ESCR, ESRate, DSM trick mode, additional copy info, CRC and extension flags.
				dwBufferIndex++;

				// Get Header Data Length
				if (dwBufferIndex > dwLength)
					break;
				wHeaderDataLength = *(pBuffer + dwBufferIndex++);
				dwBufferIndex += wHeaderDataLength;

				// Sub stream id: AC3 (10000***b), DTS (10001***b), PCM (10100***b), SUB (001*****b)
				if (dwBufferIndex >= dwLength)
					break;
				BYTE bSubStreamId = *(pBuffer + dwBufferIndex++);
				wHeaderDataLength++;
				if ((bSubStreamId >> 5) != SUB_SUBSTREAM_ID)
				{
					// Number of frame headers and first access unit pointer
					dwBufferIndex += 3;
					wHeaderDataLength += 3;
					CheckSubStreamId(bSubStreamId, audioSubtype, &bAudioFormat);
					if ((bSubStreamId >> 3) == PCM_SUBSTREAM_ID)
					{
						dwBufferIndex++;
						if (dwBufferIndex >= dwLength)
							break;
						byte = *(pBuffer + dwBufferIndex++);
						INT iQuantizationWordLength = (byte >> 6) & 0x3;
						INT iSampleRate = (byte >> 4) & 0x3;
						INT iNumAudioChannels = (byte & 0x7) + 1;
						audioSubtype->pcmAudio.iBitsPerSample = quantization_table[iQuantizationWordLength];
						audioSubtype->pcmAudio.iSampleRate = pcm_sample_rate_table[iSampleRate];
						audioSubtype->pcmAudio.iNumAudioChannels = iNumAudioChannels;
						dwBufferIndex++;
					}
				}
				dwBufferIndex += (wPacketLength - wHeaderDataLength);
			}
		}
	}
	return bAudioFormat;
}

////////////////////////////////////////////////////////////////////
/****f* MMDemux/IdentifyHeader
 * USAGE
 *  UINT IdentifyHeader(char *pFileName)
 *  UINT IdentifyHeader(const BYTE *pSearchBuffer, DWORD dwSearchBufferSize)
 * DESCRIPTION
 *  Search for any MPEG header in order to identify the file type. 
 * PARAMETERS
 *  BYTE *pSearchBuffer : buffer where to load the data.
 *  DWORD dwSearchBufferSize : number of bytes to search. Note that the size
 *    of the valid data must be dwSearchBlockSize + 4.
 * RETURN VALUE
 *  FT_AC3_AUDIO for audio AC3
 *  FT_MPEG_VIDEO for elementary video
 *  FT_MPEG_AUDIO for elementary audio
 *  FT_MPEG_SYSTEM for mpeg1 system
 *  FT_MPEG2_SYSTEM for mpeg2 system
 *  FT_AC3_AUDIO for elementary audio AC3
 *  FT_PES for pes stream
 *  FT_MPEG4_VIDEO for mpeg4 elementary video
/**********************************************************************/
UINT IdentifyHeader(char *pFileName)
{
	UINT mpeg4type = CheckMPG4type(pFileName);
	if(mpeg4type == FT_UNKNOWN)
	{
		BYTE bBuffer[READ_BUFFERSIZE];
		DWORD dwSearchBufferSize = 0;

		FILE *pFile = fopen(pFileName, "rb");
		if (!pFile)
			return FT_UNKNOWN;
		dwSearchBufferSize = fread(bBuffer, 1, READ_BUFFERSIZE, pFile);
		fclose(pFile);
		return IdentifyHeader(bBuffer, dwSearchBufferSize);
	}
	else if(mpeg4type == FT_QUICKTIME)
		return FT_UNKNOWN;
	else
		return mpeg4type;
}

////////////////////////////////////////////////////////////////////

UINT IdentifyHeader(const BYTE *pSearchBuffer, DWORD dwSearchBufferSize)
{
	const BYTE *pBuffer  = pSearchBuffer;
	DWORD dwCanBeSystem = 0;
	DWORD dwCanBeSystem2 = 0;
	DWORD dwCanBeMPEGAudio = 0;
	DWORD dwCanBeAC3Audio = 0;
	DWORD dwCanBeDtsAudio = 0;
	DWORD dwCanBeVideo = 0;
	DWORD dwCanBeVideo2 = 0;
	DWORD dwCanBeVideo4 = 0;
	DWORD dwBufferPos;
	WORD wAudioStart = 0;
	const TCHAR* sVTS = "DVDVIDEO-VTS";
	const TCHAR* sVMG = "DVDVIDEO-VMG";

	if (IsAc3Reverse(pBuffer, dwSearchBufferSize))
	{
		MmDebugLogfile((MmDebugLevelTrace, "Filetype: AC3_AUDIO"));
		return FT_AC3_AUDIO;
	}
	else if (IsPESFile(pBuffer, dwSearchBufferSize))
	{
		MmDebugLogfile((MmDebugLevelTrace, "Filetype: PES"));
		return FT_PES;
	}

	// Refuse to open RIFF (AVI and WAV files)
	if (memcmp(pSearchBuffer, "RIFF", 4) == 0)
	{
		MmDebugLogfile((MmDebugLevelTrace, "Filetype: FT_UNKNOWN"));
		return FT_UNKNOWN;
	}

	// Refuse to open Midi (MID files)
	if (memcmp(pSearchBuffer, "MThd", 4) == 0)
	{
		MmDebugLogfile((MmDebugLevelTrace, "Filetype: FT_UNKNOWN"));
		return FT_UNKNOWN;
	}

	for (dwBufferPos = 0; dwBufferPos < dwSearchBufferSize; dwBufferPos++)	
	{
		if (memcmp(sVTS, pBuffer, 12) == 0) 
		{
			MmDebugLogfile((MmDebugLevelTrace, "Filetype: DVT_VTS"));
			return FT_DVD_VTS;
		}
		else if (memcmp(sVMG, pBuffer, 12) == 0) 
		{
			MmDebugLogfile((MmDebugLevelTrace, "Filetype: DVT_VMG"));
			return FT_DVD_VMG;
		}

		if ( MATCHBYTESTREAM(pBuffer, VIDEO_OBJECT_SEQUENCE_START_CODE) ||	// reserved in Mpeg2
			MATCHBYTESTREAM(pBuffer, VOP_START_CODE) )	// reserved in Mpeg2
		{
			MmDebugLogfile((MmDebugLevelTrace, "Filetype: VideoMpeg4"));
			// for now I care only about mpeg4 video ID <-> VideoObjectLayer
			return FT_MPEG4_VIDEO;
		}

		else if (MATCHBYTESTREAM(pBuffer, PACK_START_CODE))
		{
			if ((* (pBuffer+4))>>6 == 0x01)	
			{
				DWORD dwCanbeMAX = max (dwCanBeVideo, 
					max( dwCanBeAC3Audio, dwCanBeMPEGAudio));
				if (dwCanbeMAX > 8)	
				{
					// May be not a system stream if we have found 8 headers before
					if (dwBufferPos == 0)
						dwCanBeSystem2 += 6;	
					else
						dwCanBeSystem2 += 2;	
				}
				else
				{
					MmDebugLogfile((MmDebugLevelTrace, "Filetype: MPEG2_SYSTEM"));
					return FT_MPEG2_SYSTEM;
				}
			}
			else if ((*(pBuffer+4)) >> 4 == 0x02)
			{
				DWORD dwCanbeMAX = max (dwCanBeVideo, 
					max( dwCanBeAC3Audio, dwCanBeMPEGAudio));
				if (dwCanbeMAX > 8)
				{
					// May be not a system stream if we have found 8 headers before
					if (dwBufferPos == 0)
						dwCanBeSystem += 6;	
					else
						dwCanBeSystem += 2;	
				}
				else
				{
					MmDebugLogfile((MmDebugLevelTrace, "Filetype: MPEG_SYSTEM"));
					return FT_MPEG_SYSTEM;
				}
			}
		} 
		else if ((*pBuffer) == M2T_SYNC_BYTE) 
		{
			BOOL bFound = TRUE;
			DWORD dwAd = 0;
			INT   ind = 0;
			for (; (ind < 20) && (dwBufferPos+dwAd < dwSearchBufferSize); ind++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -