📄 mfm.c
字号:
#define WMAERR_INVALIDHEADER 4
#define WMAERR_OUTOFMEMORY 5
#define WMAERR_CORRUPTDATA 6
#define WMAERR_NOTDONE 7 /* need more data to finish the work */
#define WMAERR_INVALIDSTATE 8
#define MIN_OBJECT_SIZE 24
#define DATA_OBJECT_SIZE 50
#define WMA_MAX_DATA_REQUESTED 128
#define TRUE 1
#define FALSE 0
typedef struct
{
unsigned long Data0;
unsigned long Data1;
unsigned long Data2;
unsigned long Data3;
} GUID_JD;
struct tWMA_HdrTCC
{
unsigned long currPacketOffset;
// unsigned long cbFirstPacketOffset;
// unsigned long cbCDOffset;
/* ASF header */
// unsigned long cbPacketSize;
// unsigned long cPackets;
// unsigned long cbAudioSize;
unsigned long dwLo;
// unsigned long dwHi;
unsigned short formattag;
unsigned short channels;
unsigned long samplingfreq;
unsigned long avgbitrate;
unsigned long playtime; //add by huangxm
unsigned char pData[128];
int file;
};
// added by Jason 2004/05/06
const unsigned long CLSID_CAsfHeaderObjectV0TCC[] = {0x3026b275, 0x8e66cf11, 0xa6d900aa, 0x0062ce6c}; //Jason
const unsigned long CLSID_CAsfStreamPropertiesObjectV1TCC[]= {0x9107dcb7, 0xb7a9cf11, 0x8ee600c0, 0x0c205365}; //Jason
const unsigned long CLSID_CAsfFilePropertiesObjectV1TCC[]= {0xa1dcab8c, 0x47a9cf11, 0x8ee400c0, 0x0c205365}; //Huangxm
const unsigned long CLSID_AsfXStreamTypeAcmAudioTCC[]= {0x409e69f8, 0x4d5bcf11, 0xa8fd0080, 0x5f5c442b}; //Jason
/*
// Modified by HHC on V160P1 [04/05/20]
unsigned char g_pmid[20];
extern unsigned char gSerialNumber[LENGTH_SERIALNUMBER];*/
/*
const unsigned char g_pmid[20] =
{
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x20,
0x30, 0x37, 0x34, 0x34, 0x37, 0x30, 0x33, 0x30, 0x31, 0x31
};
*/
//****************************************************************************
//
// The function checks the unsupported wma file.
// 200/05/06 Jason
//****************************************************************************
unsigned short WMA_GetData(struct tWMA_HdrTCC *Header, unsigned short num_bytes)
{
MediaFileSeek((HMEDIAFILE)Header->file, (INT)Header->currPacketOffset, SEEK_SET);
return MediaFileRead((HMEDIAFILE)Header->file, (BYTE *)Header->pData, (INT)num_bytes);
}
int WMA_LoadHeaderObjectTCC( struct tWMA_HdrTCC *Header)
{
GUID_JD objectId;
unsigned short num_bytes;
unsigned short cbActual;
unsigned char *pData;
num_bytes = 30; //fix
cbActual = WMA_GetData(Header, num_bytes);
if(cbActual != num_bytes)
{
return WMAERR_BUFFERTOOSMALL;
}
Header->currPacketOffset += cbActual;
pData = Header->pData;
// extract ObjectID
objectId.Data0 = pData[0]<<24 | pData[1]<<16 | pData[2]<<8 | pData[3];
objectId.Data1 = pData[4+0]<<24 | pData[4+1]<<16 | pData[4+2]<<8 | pData[4+3];
objectId.Data2 = pData[8+0]<<24 | pData[8+1]<<16 | pData[8+2]<<8 | pData[8+3];
objectId.Data3 = pData[12+0]<<24 | pData[12+1]<<16 | pData[12+2]<<8 | pData[12+3];
if( objectId.Data0 != CLSID_CAsfHeaderObjectV0TCC[0] ||
objectId.Data1 != CLSID_CAsfHeaderObjectV0TCC[1] ||
objectId.Data2 != CLSID_CAsfHeaderObjectV0TCC[2] ||
objectId.Data3 != CLSID_CAsfHeaderObjectV0TCC[3] )
{
return WMAERR_INVALIDHEADER;
}
// use all
Header->dwLo = pData[17]<<8 | pData[16];
return WMAERR_OK;
}
int WMA_LoadObjectHeaderTCC(struct tWMA_HdrTCC *Header, GUID_JD *pObjectId)
{
unsigned short num_bytes;
unsigned short cbActual;
unsigned char *pData;
num_bytes = MIN_OBJECT_SIZE; /*check!!*/
cbActual = WMA_GetData( Header,num_bytes);
if(cbActual != num_bytes)
{
return WMAERR_BUFFERTOOSMALL;
}
Header->currPacketOffset += cbActual;
pData = Header->pData;
// extract ObjectID
pObjectId->Data0 = pData[0]<<24 | pData[1]<<16 | pData[2]<<8 | pData[3];
pObjectId->Data1 = pData[4+0]<<24 | pData[4+1]<<16 | pData[4+2]<<8 | pData[4+3];
pObjectId->Data2 = pData[8+0]<<24 | pData[8+1]<<16 | pData[8+2]<<8 | pData[8+3];
pObjectId->Data3 = pData[12+0]<<24 | pData[12+1]<<16 | pData[12+2]<<8| pData[12+3];
//extract qwSize
Header->dwLo = pData[17]<<8 | pData[16];
//Header->dwHi = pData[19]<<8 | pData[18];
return WMAERR_OK;
}
/***********************************************
* Extract the Contents Data
***********************************************/
int WMA_LoadStreamPropertiesObjectTCC(struct tWMA_HdrTCC *Header, unsigned long cbSize)
{
GUID_JD objectId;
unsigned short num_bytes;
unsigned short cbActual;
unsigned char *pData;
cbSize -= MIN_OBJECT_SIZE;
num_bytes = 64; //read 64 bytes
if(num_bytes > cbSize)
{
return WMAERR_BUFFERTOOSMALL;
}
cbActual = WMA_GetData( Header,num_bytes);
if(cbActual != num_bytes)
{
return WMAERR_BUFFERTOOSMALL;
}
pData = Header->pData;
objectId.Data0 = pData[0]<<24 | pData[1]<<16 | pData[2]<<8 | pData[3];
objectId.Data1 = pData[4+0]<<24 | pData[4+1]<<16 | pData[4+2]<<8 | pData[4+3];
objectId.Data2 = pData[8+0]<<24 | pData[8+1]<<16 | pData[8+2]<<8 | pData[8+3];
objectId.Data3 = pData[12+0]<<24 | pData[12+1]<<16 | pData[12+2]<<8 | pData[12+3];
if( objectId.Data0 != CLSID_AsfXStreamTypeAcmAudioTCC[0] ||
objectId.Data1 != CLSID_AsfXStreamTypeAcmAudioTCC[1] ||
objectId.Data2 != CLSID_AsfXStreamTypeAcmAudioTCC[2] ||
objectId.Data3 != CLSID_AsfXStreamTypeAcmAudioTCC[3] )
{
return WMAERR_INVALIDHEADER;
}
Header->formattag= (pData[54+1]<<8 | pData[54]);
Header->channels= (pData[56+1]<<8 | pData[56]);
Header->samplingfreq= pData[58+3]<<24 | pData[58+2]<<16 | pData[58+1]<<8 | pData[58];
Header->avgbitrate= (pData[62+1]<<8 | pData[62]) << 3;
return WMAERR_OK;
}
/***********************************************
* Extract the File Property Data
***********************************************/
int WMA_LoadFilePropertiesObjectTCC(struct tWMA_HdrTCC *Header, unsigned long cbSize)
{
unsigned short num_bytes;
unsigned short cbActual;
unsigned char *pData;
unsigned long dwPlayDuration, dwPreroll;
cbSize -= MIN_OBJECT_SIZE;
num_bytes = 80; //read 88 bytes
if(num_bytes > cbSize)
{
return WMAERR_BUFFERTOOSMALL;
}
cbActual = WMA_GetData( Header,num_bytes);
if(cbActual != num_bytes)
{
return WMAERR_BUFFERTOOSMALL;
}
pData = Header->pData;
dwPlayDuration = *(unsigned long *)&pData[0x28];
dwPlayDuration /= 10000;
dwPlayDuration += (*(unsigned long *)&pData[0x2C]) * 429000 ;
// 429 = 0x100000000 / 10000
dwPreroll = *(unsigned long *)&pData[0x38];
Header->playtime = (dwPlayDuration - dwPreroll) / 1000;
return WMAERR_OK;
}
int WMA_ParseAsfHeaderTCC(struct tWMA_HdrTCC *Header)
{
int wmarc;
GUID_JD objId;
unsigned long cbFirstPacketOffset;
unsigned long cbDataObjectOffset;
/* ASF Header Object */
wmarc = WMA_LoadHeaderObjectTCC(Header);
if(wmarc != WMAERR_OK)
{
return wmarc;
}
cbDataObjectOffset = Header->dwLo;
cbFirstPacketOffset = Header->dwLo +DATA_OBJECT_SIZE;
/* Scan Header Objects */
while(Header->currPacketOffset < cbFirstPacketOffset)
{
wmarc = WMA_LoadObjectHeaderTCC(Header, &objId);
if(wmarc != WMAERR_OK) {
return wmarc;
}
if( objId.Data0 == CLSID_CAsfStreamPropertiesObjectV1TCC[0] &&
objId.Data1 == CLSID_CAsfStreamPropertiesObjectV1TCC[1] &&
objId.Data2 == CLSID_CAsfStreamPropertiesObjectV1TCC[2] &&
objId.Data3 == CLSID_CAsfStreamPropertiesObjectV1TCC[3] )
{
wmarc = WMA_LoadStreamPropertiesObjectTCC(Header, Header->dwLo);
if(wmarc != WMAERR_OK) {
return wmarc;
}
}
else if( objId.Data0 == CLSID_CAsfFilePropertiesObjectV1TCC[0] &&
objId.Data1 == CLSID_CAsfFilePropertiesObjectV1TCC[1] &&
objId.Data2 == CLSID_CAsfFilePropertiesObjectV1TCC[2] &&
objId.Data3 == CLSID_CAsfFilePropertiesObjectV1TCC[3] )
{
wmarc = WMA_LoadFilePropertiesObjectTCC(Header, Header->dwLo);
if(wmarc != WMAERR_OK) {
return wmarc;
}
/* skip over this object */
Header->currPacketOffset += Header->dwLo - MIN_OBJECT_SIZE;
}
else {
/* skip over this object */
Header->currPacketOffset += Header->dwLo - MIN_OBJECT_SIZE;
}
}
//set file pointer to data object
MediaFileSeek( (HMEDIAFILE)(Header->file), (INT)cbDataObjectOffset, SEEK_SET);
return WMAERR_OK;
}
UINT MediaFileGetWMAFormat(HMEDIAFILE hmmio, WAVEFORMATEX *pWfx, UINT32 *pdwTimeLength)
{
int iResult; /* api result */
struct tWMA_HdrTCC Header; /* file header */
memset(&Header,0,sizeof(Header)); //clr data buffer
Header.file = (INT)hmmio;
iResult = WMA_ParseAsfHeaderTCC(&Header);
if(iResult != WMAERR_OK)
return MMIOERR_ACCESSDENIED;
if(Header.formattag != WAVE_FORMAT_WMA)
return MMIOERR_ACCESSDENIED;
pWfx->wFormatTag = Header.formattag;
pWfx->cbSize = 0;
pWfx->nChannels = Header.channels;
pWfx->wBitsPerSample = 16;
pWfx->nBlockAlign = 1;
pWfx->nAvgBytesPerSec = Header.avgbitrate / 8;
pWfx->nSamplesPerSec = Header.samplingfreq;
*pdwTimeLength = Header.playtime;
if(Header.avgbitrate > 196000 )
return MMIOERR_ACCESSDENIED;
#ifdef EVAL_VERSION
iResult = CheckCorrectWMAFile(&Header);
if(iResult ==0 )
return MMIOERR_ACCESSDENIED;
#endif
return MMSYSERR_NOERROR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -