/bb_waze_code/src/win32/wince_env/maplay/PlayerMpg.cpp
https://github.com/noamkfir/WazeWP7 · C++ · 579 lines · 459 code · 100 blank · 20 comment · 158 complexity · 9c8e1dfb034f9cd9878fc8b198e33dd6 MD5 · raw file
- #include <windows.h>
- #include "maplay.h"
- #include "helper.h"
- #include "player.h"
- BOOL CPlayer::MpgOpenFile(LPCTSTR pszFile)
- {
- if (!IsValidFile(pszFile))
- return FALSE;
- if (!m_Reader.Open(pszFile))
- return FALSE;
- _tcscpy(m_szFile, pszFile);
- if (!MpgScanFile()) {
- m_Reader.Close();
- return FALSE;
- }
- m_fOpen = OPEN_MPG_FILE;
- return TRUE;
- }
- BOOL CPlayer::MpgScanFile()
- {
- if (m_Options.fScanMpegCompletely)
- return MpgScanFileCompletely();
- else
- return MpgScanFileNormally();
- }
- #if 0
- BOOL CPlayer::MpgScanFileNormally()
- {
- // ̈ʒũt[݂̂XL
- int nFrameSize = 0;
- int nFrameCount = 0;
- int nAvgBitrate = 0;
- int nCount;
- DWORD cbRead;
- LONGLONG llCur, llPrev;
- MPEG_AUDIO_INFO infoCur, infoPrev;
- BYTE bBuff[MPG_SCAN_BUFF_LEN];
- memset(&m_Info, 0, sizeof(MPEG_AUDIO_INFO));
- #define MPG_MAX_SCAN_FRAME 16
- #define MAX_SCAN_SEP 8
- LONGLONG llMax = 0;
- for (int i = 0; i < MAX_SCAN_SEP; i++) {
- // XLʒům
- llCur = m_Reader.GetSize() * (i + 1) / (MAX_SCAN_SEP + 1);
- if (llCur < llMax)
- continue;
-
- m_Reader.SetPointer(llCur, FILE_BEGIN);
- llCur = m_Reader.ScanAudioHeader();
- if (llCur == MAXLONGLONG)
- return FALSE;
- memset(&infoCur, 0, sizeof(MPEG_AUDIO_INFO));
- memset(&infoPrev, 0, sizeof(MPEG_AUDIO_INFO));
-
- nCount = 0;
- llPrev = llCur;
- while (TRUE) {
- if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
- break;
- if (cbRead < 4)
- break;
- if (!ParseHeader(bBuff, &infoCur)) {
- nCount = max(0, nCount - 1);
- nFrameSize -= infoPrev.nFrameSize;
- nAvgBitrate -= infoPrev.nBitRate;
- m_Reader.SetPointer(llPrev + 1, FILE_BEGIN);
- llCur = m_Reader.ScanAudioHeader();
- if (llCur == MAXLONGLONG)
- break;
- llPrev = llCur;
- continue;
- }
- if (nCount) {
- if (infoCur.nVersion != infoPrev.nVersion ||
- infoCur.nLayer != infoPrev.nLayer ||
- infoCur.nSamplingRate != infoPrev.nSamplingRate) {
- nCount = max(0, nCount - 1);
- nFrameSize -= infoPrev.nFrameSize;
- nAvgBitrate -= infoPrev.nBitRate;
- m_Reader.SetPointer(llPrev + 1, FILE_BEGIN);
- llCur = m_Reader.ScanAudioHeader();
- if (llCur == MAXLONGLONG)
- break;
- llPrev = llCur;
- continue;
- }
- if (nCount == 1) m_Info = infoPrev;
- }
- nCount++;
- nFrameSize += infoCur.nFrameSize;
- nAvgBitrate += infoCur.nBitRate;
- infoPrev = infoCur;
- llPrev = llCur;
- llCur += infoCur.nFrameSize;
- llMax = llCur;
- if (nCount >= MPG_MAX_SCAN_FRAME)
- break;
- if (m_Reader.SetPointer(llCur, FILE_BEGIN) == MAXLONGLONG)
- break;
- }
- if (!nCount)
- break;
- nFrameCount += nCount;
- }
-
- if (!nFrameCount)
- return FALSE;
-
- m_Info.nFrameSize = nFrameSize / nFrameCount; // t[TCY̕
- m_Info.nBitRate = (int)((double)nAvgBitrate / nFrameCount + 0.5);
- LONGLONG llSize = m_Reader.GetSize();
- nFrameCount = int(llSize / m_Info.nFrameSize);
- m_nDuration = (DWORD)m_Info.nSamplesPerFrame * nFrameCount;
- m_Reader.SetPointer(0, FILE_BEGIN);
- return TRUE;
- }
- #else
- BOOL CPlayer::MpgScanFileNormally()
- {
- // ̈ʒũt[݂̂XL
- DWORD cbRead;
- LONGLONG llCur, llSize;
- MPEG_AUDIO_INFO infoCur, infoNext;
- BYTE bBuff[MPG_SCAN_BUFF_LEN];
- int nFrameCount, nSkip;
- memset(&m_Info, 0, sizeof(MPEG_AUDIO_INFO));
- memset(&infoCur, 0, sizeof(MPEG_AUDIO_INFO));
- memset(&infoNext, 0, sizeof(MPEG_AUDIO_INFO));
- m_Reader.SetPointer(0, FILE_BEGIN);
- llCur = m_Reader.ScanAudioHeader();
- if (llCur == MAXLONGLONG)
- return FALSE;
-
- while (TRUE) {
- if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
- return FALSE;
- if (cbRead < 4)
- return FALSE;
- if (!ParseHeader(bBuff, &infoCur)) {
- m_Reader.SetPointer(llCur + 1, FILE_BEGIN);
- llCur = m_Reader.ScanAudioHeader();
- if (llCur == MAXLONGLONG)
- return FALSE;
- continue;
- }
- if (m_Reader.SetPointer(llCur + infoCur.nFrameSize, FILE_BEGIN) == MAXLONGLONG)
- return FALSE;
- if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
- return FALSE;
- if (cbRead < 4)
- return FALSE;
- if (!ParseHeader(bBuff, &infoNext)) {
- m_Reader.SetPointer(llCur + 1, FILE_BEGIN);
- llCur = m_Reader.ScanAudioHeader();
- if (llCur == MAXLONGLONG)
- return FALSE;
- continue;
- }
- if (infoCur.nVersion != infoNext.nVersion ||
- infoCur.nLayer != infoNext.nLayer ||
- infoCur.nSamplingRate != infoNext.nSamplingRate) {
- m_Reader.SetPointer(llCur + 1, FILE_BEGIN);
- llCur = m_Reader.ScanAudioHeader();
- if (llCur == MAXLONGLONG)
- return FALSE;
- continue;
- }
- m_Info = infoCur;
- if (m_Info.nVersion == 2)
- nSkip = m_Info.nChannels == 2 ? 17 : 9;
- else
- nSkip = m_Info.nChannels == 2 ? 32 : 17;
- if (m_Reader.SetPointer(llCur + nSkip + 4, FILE_BEGIN) == MAXLONGLONG)
- return FALSE;
- if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
- return FALSE;
- if (cbRead < 4)
- return FALSE;
- // Xing header
- if (bBuff[0] == 'X' && bBuff[1] == 'i' && bBuff[2] == 'n' && bBuff[3] == 'g') {
- if (m_Reader.SetPointer(4, FILE_CURRENT) == MAXLONGLONG)
- return FALSE;
-
- if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
- return FALSE;
- if (cbRead < 4)
- return FALSE;
- nFrameCount = bBuff[0] << 24 | bBuff[1] << 16 | bBuff[2] << 8 | bBuff[3];
- llSize = m_Reader.GetSize();
- m_nDuration = (DWORD)m_Info.nSamplesPerFrame * nFrameCount;
- m_Info.nFrameSize = (int)(llSize / nFrameCount);
- m_Info.nBitRate = (int)((llSize * 8/ (m_nDuration / m_Info.nSamplingRate) + 500) / 1000);
- }
- // VBRI header
- else if (bBuff[0] == 'V' && bBuff[1] == 'B' && bBuff[2] == 'R' && bBuff[3] == 'I') {
- if (m_Reader.SetPointer(10, FILE_CURRENT) == MAXLONGLONG)
- return FALSE;
-
- if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
- return FALSE;
- if (cbRead < 4)
- return FALSE;
- nFrameCount = bBuff[0] << 24 | bBuff[1] << 16 | bBuff[2] << 8 | bBuff[3];
- llSize = m_Reader.GetSize();
- m_nDuration = (DWORD)m_Info.nSamplesPerFrame * nFrameCount;
- m_Info.nFrameSize = (int)(llSize / nFrameCount);
- m_Info.nBitRate = (int)((llSize * 8/ (m_nDuration / m_Info.nSamplingRate) + 500) / 1000);
- }
- else {
- // CBR
- llSize = m_Reader.GetSize();
- nFrameCount = int(llSize / m_Info.nFrameSize);
- m_nDuration = (DWORD)m_Info.nSamplesPerFrame * nFrameCount;
- }
- m_Reader.SetPointer(0, FILE_BEGIN);
- return TRUE;
- }
- }
- #endif
- BOOL CPlayer::MpgScanFileCompletely()
- {
- // t[SɃXL
- int nCount = 0;
- int nFrameSize = 0;
- int nAvgBitrate = 0;
- DWORD cbRead;
- MPEG_AUDIO_INFO infoCur, infoPrev;
- BYTE bBuff[MPG_SCAN_BUFF_LEN];
- LONGLONG llCur, llPrev;
- memset(&m_Info, 0, sizeof(MPEG_AUDIO_INFO));
- memset(&infoCur, 0, sizeof(MPEG_AUDIO_INFO));
- memset(&infoPrev, 0, sizeof(MPEG_AUDIO_INFO));
- m_Reader.SetPointer(0, FILE_BEGIN);
- llCur = m_Reader.ScanAudioHeader();
- if (llCur == MAXLONGLONG)
- return FALSE;
- llPrev = llCur;
- while (TRUE) {
- if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
- break;
- if (cbRead < 4)
- break;
- if (!ParseHeader(bBuff, &infoCur)) {
- nCount = max(0, nCount - 1);
- nFrameSize -= infoPrev.nFrameSize;
- nAvgBitrate -= infoPrev.nBitRate;
- m_Reader.SetPointer(llPrev + 1, FILE_BEGIN);
- llCur = m_Reader.ScanAudioHeader();
- if (llCur == MAXLONGLONG)
- break;
- llPrev = llCur;
- continue;
- }
- if (nCount) {
- if (infoCur.nVersion != infoPrev.nVersion ||
- infoCur.nLayer != infoPrev.nLayer ||
- infoCur.nSamplingRate != infoPrev.nSamplingRate) {
- nCount = max(0, nCount - 1);
- nFrameSize -= infoPrev.nFrameSize;
- nAvgBitrate -= infoPrev.nBitRate;
- m_Reader.SetPointer(llPrev + 1, FILE_BEGIN);
- llCur = m_Reader.ScanAudioHeader();
- if (llCur == MAXLONGLONG)
- break;
- llPrev = llCur;
- continue;
- }
- if (nCount == 1) m_Info = infoPrev;
- }
- nCount++;
- nFrameSize += infoCur.nFrameSize;
- nAvgBitrate += infoCur.nBitRate;
- infoPrev = infoCur;
- llPrev = llCur;
- llCur += infoCur.nFrameSize;
- if (m_Reader.SetPointer(llCur, FILE_BEGIN) == MAXLONGLONG)
- break;
- }
- if (!nCount)
- return FALSE;
- m_Info.nFrameSize = nFrameSize / nCount; // t[TCY̕
- m_Info.nBitRate = (int)((double)nAvgBitrate / nCount + 0.5);
- m_nDuration = (DWORD)m_Info.nSamplesPerFrame * nCount;
- m_Reader.SetPointer(0, FILE_BEGIN);
- return TRUE;
- }
- BOOL CPlayer::MpgSeekFile(long lTime)
- {
- BOOL fRet = FALSE;
- BOOL fPause = FALSE;
- // Ԃ̕ϊ
- int nNew = (int)((double)m_Info.nSamplingRate * lTime / 1000);
- int nFrames = nNew / m_Info.nSamplesPerFrame;
- LONGLONG llOld;
- if (m_Options.fScanMpegCompletely) {
- llOld = m_Reader.SetPointer(0, FILE_BEGIN);
- if (m_Reader.ScanAudioHeader(m_Info.nVersion, m_Info.nLayer) != MAXLONGLONG) {
- int nCount = 0;
- BYTE bBuff[4];
- DWORD dwRead;
- while (m_Reader.Read(bBuff, sizeof(bBuff), &dwRead) && dwRead == 4) {
- // scan header
- MPEG_AUDIO_INFO info;
- if (ParseHeader(bBuff, &info)) {
- if (++nCount >= nFrames) {
- m_Reader.SetPointer(-4, FILE_CURRENT);
- fRet = TRUE;
- break;
- }
- else {
- m_Reader.SetPointer(info.nFrameSize - 4, FILE_CURRENT);
- }
- }
- else {
- m_Reader.SetPointer(-3, FILE_CURRENT);
- if (m_Reader.ScanAudioHeader(m_Info.nVersion, m_Info.nLayer) == MAXLONGLONG)
- break;
- }
- }
- }
- }
- else {
- LONGLONG llOffset = m_Info.nFrameSize * nFrames;
- // seek the offset
- llOld = m_Reader.SetPointer(llOffset, FILE_BEGIN);
- if (llOld != MAXLONGLONG) {
- if (m_Reader.ScanAudioHeader(m_Info.nVersion, m_Info.nLayer) != MAXLONGLONG)
- fRet = TRUE;
- }
- }
- if (fRet) {
- // V[Ň㏈
- m_fSeek = TRUE;
- m_nSeek = nNew;
- m_Output.Reset(); // TEhobt@̓NA
- }
- else {
- m_Reader.SetPointer(llOld, FILE_BEGIN);
- }
- return fRet;
- }
- int CPlayer::MpgRender(LPBYTE pbInBuf, DWORD cbInBuf, LPDWORD pcbProceed)
- {
- int nRet;
- BOOL fNeedOutput = FALSE;
- DWORD cbInput, cbOutput;
- *pcbProceed = 0;
- do {
- // ~tÕ`FbN
- if (m_fStop)
- return MAD_OK;
- // o̓obt@̊m
- if (!m_pOutHdr || !m_cbOutBufLeft) {
- if (m_pOutHdr) {
- OutputBuffer(m_pOutHdr, m_cbOutBuf - m_cbOutBufLeft);
- m_cbOutBufLeft = 0;
- m_pOutHdr = NULL;
- }
- m_pOutHdr = m_Output.GetBuffer();
- m_cbOutBufLeft = m_cbOutBuf;
- if (m_fSeek)
- return MAD_OK;
- if (m_fStop)
- return MAD_OK;
- }
- // f[^̃`FbN
- if (!fNeedOutput && !CheckAudioHeader(pbInBuf + *pcbProceed)) {
- while (++*pcbProceed < cbInBuf - 4) {
- MPEG_AUDIO_INFO info;
- if (ParseHeader(pbInBuf + *pcbProceed, &info) &&
- info.nVersion == m_Info.nVersion &&
- info.nLayer == m_Info.nLayer &&
- info.nSamplingRate == m_Info.nSamplingRate)
- break;
- }
- if (*pcbProceed > cbInBuf - 4)
- return MAD_NEED_MORE_INPUT;
- }
- // fR[h (1t[)
- nRet = m_Decoder.Decode(pbInBuf + *pcbProceed, fNeedOutput ? 0 : cbInBuf - *pcbProceed,
- (LPBYTE)m_pOutHdr->lpData + (m_cbOutBuf - m_cbOutBufLeft),
- m_cbOutBufLeft, &cbOutput, &cbInput, 16, FALSE);
- switch (nRet) {
- case MAD_FATAL_ERR:
- // Zbg
- m_Decoder.Reset();
- case MAD_ERR:
- *pcbProceed += 1; // 1oCgi߂
- break;
- case MAD_NEED_MORE_OUTPUT:
- fNeedOutput = TRUE;
- *pcbProceed += cbInput;
- m_cbOutBufLeft -= cbOutput;
- break;
- case MAD_OK:
- fNeedOutput = FALSE;
- *pcbProceed += cbInput;
- m_cbOutBufLeft -= cbOutput;
- break;
- }
- }
- while (nRet != MAD_NEED_MORE_INPUT || fNeedOutput);
- return nRet;
- }
- DWORD CPlayer::MpgPlayerThread()
- {
- #define MPG_FILE_READ_SIZE (MPG_FILE_BUFF_LEN * 8)
- BOOL fRet;
- BOOL fFlush = FALSE;
- DWORD cbBufSize, cbInBuf, cbInBufLeft = 0;
- LPBYTE pbRead = new BYTE[MPG_FILE_READ_SIZE];
- cbBufSize = MPG_FILE_READ_SIZE;
- if (!pbRead) {
- pbRead = new BYTE[MPG_FILE_BUFF_LEN];
- cbBufSize = MPG_FILE_BUFF_LEN;
- if (!pbRead) return RET_ERROR;
- }
- // fR[hJn
- while (TRUE) {
- // ~tÕ`FbN
- if (m_fStop) {
- delete [] pbRead;
- return RET_STOP;
- }
- {
- // Critical SectioñZbg
- CAutoLock lock(&m_csecThread);
- if (m_fSeek) {
- if (m_Status == MAP_STATUS_PLAY)
- m_fPlay = TRUE;
- m_Reverb.Reset();
- m_Echo.Reset();
- m_BassBoost.Reset();
- m_3DChorus.Reset();
- m_Output.Reset();
- m_Decoder.Reset();
-
- cbInBufLeft = 0;
- m_fSeek = FALSE;
- m_pOutHdr = NULL;
- continue;
- }
- // ǂݍ
- fRet = m_Reader.Read(pbRead + cbInBufLeft, cbBufSize - cbInBufLeft, &cbInBuf);
- if (!fRet || !cbInBuf) {
- if (!fRet && GetLastError() != ERROR_SUCCESS) {
- delete [] pbRead;
- return RET_ERROR;
- }
- fFlush = TRUE;
- }
- cbInBufLeft += cbInBuf;
- cbInBuf = 0;
- }
- if (fFlush) {
- if (!UnpreparePlayback(TRUE)) {
- fFlush = FALSE;
- continue;
- }
- delete [] pbRead;
- return RET_EOF;
- }
- if (MpgRender(pbRead, cbInBufLeft, &cbInBuf) == MAD_FATAL_ERR) {
- delete [] pbRead;
- return RET_ERROR;
- }
- if (m_fSuppress) {
- delete [] pbRead;
- return RET_EOF;
- }
- memmove(pbRead, pbRead + cbInBuf, cbInBufLeft - cbInBuf);
- cbInBufLeft -= cbInBuf;
- }
- }
- void CPlayer::MpgStop()
- {
- m_Reader.SetPointer(0, FILE_BEGIN);
- }
- void CPlayer::MpgClose()
- {
- m_Reader.Close();
- m_Receiver.Close();
- }
- BOOL CPlayer::MpgGetId3Tag(ID3TAGV1* pTag)
- {
- return ::GetId3Tag(m_szFile, pTag);
- }