/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

  1. #include <windows.h>
  2. #include "maplay.h"
  3. #include "helper.h"
  4. #include "player.h"
  5. BOOL CPlayer::MpgOpenFile(LPCTSTR pszFile)
  6. {
  7. if (!IsValidFile(pszFile))
  8. return FALSE;
  9. if (!m_Reader.Open(pszFile))
  10. return FALSE;
  11. _tcscpy(m_szFile, pszFile);
  12. if (!MpgScanFile()) {
  13. m_Reader.Close();
  14. return FALSE;
  15. }
  16. m_fOpen = OPEN_MPG_FILE;
  17. return TRUE;
  18. }
  19. BOOL CPlayer::MpgScanFile()
  20. {
  21. if (m_Options.fScanMpegCompletely)
  22. return MpgScanFileCompletely();
  23. else
  24. return MpgScanFileNormally();
  25. }
  26. #if 0
  27. BOOL CPlayer::MpgScanFileNormally()
  28. {
  29. // ̈ʒũt[݂̂XL
  30. int nFrameSize = 0;
  31. int nFrameCount = 0;
  32. int nAvgBitrate = 0;
  33. int nCount;
  34. DWORD cbRead;
  35. LONGLONG llCur, llPrev;
  36. MPEG_AUDIO_INFO infoCur, infoPrev;
  37. BYTE bBuff[MPG_SCAN_BUFF_LEN];
  38. memset(&m_Info, 0, sizeof(MPEG_AUDIO_INFO));
  39. #define MPG_MAX_SCAN_FRAME 16
  40. #define MAX_SCAN_SEP 8
  41. LONGLONG llMax = 0;
  42. for (int i = 0; i < MAX_SCAN_SEP; i++) {
  43. // XLʒům
  44. llCur = m_Reader.GetSize() * (i + 1) / (MAX_SCAN_SEP + 1);
  45. if (llCur < llMax)
  46. continue;
  47. m_Reader.SetPointer(llCur, FILE_BEGIN);
  48. llCur = m_Reader.ScanAudioHeader();
  49. if (llCur == MAXLONGLONG)
  50. return FALSE;
  51. memset(&infoCur, 0, sizeof(MPEG_AUDIO_INFO));
  52. memset(&infoPrev, 0, sizeof(MPEG_AUDIO_INFO));
  53. nCount = 0;
  54. llPrev = llCur;
  55. while (TRUE) {
  56. if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
  57. break;
  58. if (cbRead < 4)
  59. break;
  60. if (!ParseHeader(bBuff, &infoCur)) {
  61. nCount = max(0, nCount - 1);
  62. nFrameSize -= infoPrev.nFrameSize;
  63. nAvgBitrate -= infoPrev.nBitRate;
  64. m_Reader.SetPointer(llPrev + 1, FILE_BEGIN);
  65. llCur = m_Reader.ScanAudioHeader();
  66. if (llCur == MAXLONGLONG)
  67. break;
  68. llPrev = llCur;
  69. continue;
  70. }
  71. if (nCount) {
  72. if (infoCur.nVersion != infoPrev.nVersion ||
  73. infoCur.nLayer != infoPrev.nLayer ||
  74. infoCur.nSamplingRate != infoPrev.nSamplingRate) {
  75. nCount = max(0, nCount - 1);
  76. nFrameSize -= infoPrev.nFrameSize;
  77. nAvgBitrate -= infoPrev.nBitRate;
  78. m_Reader.SetPointer(llPrev + 1, FILE_BEGIN);
  79. llCur = m_Reader.ScanAudioHeader();
  80. if (llCur == MAXLONGLONG)
  81. break;
  82. llPrev = llCur;
  83. continue;
  84. }
  85. if (nCount == 1) m_Info = infoPrev;
  86. }
  87. nCount++;
  88. nFrameSize += infoCur.nFrameSize;
  89. nAvgBitrate += infoCur.nBitRate;
  90. infoPrev = infoCur;
  91. llPrev = llCur;
  92. llCur += infoCur.nFrameSize;
  93. llMax = llCur;
  94. if (nCount >= MPG_MAX_SCAN_FRAME)
  95. break;
  96. if (m_Reader.SetPointer(llCur, FILE_BEGIN) == MAXLONGLONG)
  97. break;
  98. }
  99. if (!nCount)
  100. break;
  101. nFrameCount += nCount;
  102. }
  103. if (!nFrameCount)
  104. return FALSE;
  105. m_Info.nFrameSize = nFrameSize / nFrameCount; // t[TCY̕
  106. m_Info.nBitRate = (int)((double)nAvgBitrate / nFrameCount + 0.5);
  107. LONGLONG llSize = m_Reader.GetSize();
  108. nFrameCount = int(llSize / m_Info.nFrameSize);
  109. m_nDuration = (DWORD)m_Info.nSamplesPerFrame * nFrameCount;
  110. m_Reader.SetPointer(0, FILE_BEGIN);
  111. return TRUE;
  112. }
  113. #else
  114. BOOL CPlayer::MpgScanFileNormally()
  115. {
  116. // ̈ʒũt[݂̂XL
  117. DWORD cbRead;
  118. LONGLONG llCur, llSize;
  119. MPEG_AUDIO_INFO infoCur, infoNext;
  120. BYTE bBuff[MPG_SCAN_BUFF_LEN];
  121. int nFrameCount, nSkip;
  122. memset(&m_Info, 0, sizeof(MPEG_AUDIO_INFO));
  123. memset(&infoCur, 0, sizeof(MPEG_AUDIO_INFO));
  124. memset(&infoNext, 0, sizeof(MPEG_AUDIO_INFO));
  125. m_Reader.SetPointer(0, FILE_BEGIN);
  126. llCur = m_Reader.ScanAudioHeader();
  127. if (llCur == MAXLONGLONG)
  128. return FALSE;
  129. while (TRUE) {
  130. if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
  131. return FALSE;
  132. if (cbRead < 4)
  133. return FALSE;
  134. if (!ParseHeader(bBuff, &infoCur)) {
  135. m_Reader.SetPointer(llCur + 1, FILE_BEGIN);
  136. llCur = m_Reader.ScanAudioHeader();
  137. if (llCur == MAXLONGLONG)
  138. return FALSE;
  139. continue;
  140. }
  141. if (m_Reader.SetPointer(llCur + infoCur.nFrameSize, FILE_BEGIN) == MAXLONGLONG)
  142. return FALSE;
  143. if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
  144. return FALSE;
  145. if (cbRead < 4)
  146. return FALSE;
  147. if (!ParseHeader(bBuff, &infoNext)) {
  148. m_Reader.SetPointer(llCur + 1, FILE_BEGIN);
  149. llCur = m_Reader.ScanAudioHeader();
  150. if (llCur == MAXLONGLONG)
  151. return FALSE;
  152. continue;
  153. }
  154. if (infoCur.nVersion != infoNext.nVersion ||
  155. infoCur.nLayer != infoNext.nLayer ||
  156. infoCur.nSamplingRate != infoNext.nSamplingRate) {
  157. m_Reader.SetPointer(llCur + 1, FILE_BEGIN);
  158. llCur = m_Reader.ScanAudioHeader();
  159. if (llCur == MAXLONGLONG)
  160. return FALSE;
  161. continue;
  162. }
  163. m_Info = infoCur;
  164. if (m_Info.nVersion == 2)
  165. nSkip = m_Info.nChannels == 2 ? 17 : 9;
  166. else
  167. nSkip = m_Info.nChannels == 2 ? 32 : 17;
  168. if (m_Reader.SetPointer(llCur + nSkip + 4, FILE_BEGIN) == MAXLONGLONG)
  169. return FALSE;
  170. if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
  171. return FALSE;
  172. if (cbRead < 4)
  173. return FALSE;
  174. // Xing header
  175. if (bBuff[0] == 'X' && bBuff[1] == 'i' && bBuff[2] == 'n' && bBuff[3] == 'g') {
  176. if (m_Reader.SetPointer(4, FILE_CURRENT) == MAXLONGLONG)
  177. return FALSE;
  178. if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
  179. return FALSE;
  180. if (cbRead < 4)
  181. return FALSE;
  182. nFrameCount = bBuff[0] << 24 | bBuff[1] << 16 | bBuff[2] << 8 | bBuff[3];
  183. llSize = m_Reader.GetSize();
  184. m_nDuration = (DWORD)m_Info.nSamplesPerFrame * nFrameCount;
  185. m_Info.nFrameSize = (int)(llSize / nFrameCount);
  186. m_Info.nBitRate = (int)((llSize * 8/ (m_nDuration / m_Info.nSamplingRate) + 500) / 1000);
  187. }
  188. // VBRI header
  189. else if (bBuff[0] == 'V' && bBuff[1] == 'B' && bBuff[2] == 'R' && bBuff[3] == 'I') {
  190. if (m_Reader.SetPointer(10, FILE_CURRENT) == MAXLONGLONG)
  191. return FALSE;
  192. if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
  193. return FALSE;
  194. if (cbRead < 4)
  195. return FALSE;
  196. nFrameCount = bBuff[0] << 24 | bBuff[1] << 16 | bBuff[2] << 8 | bBuff[3];
  197. llSize = m_Reader.GetSize();
  198. m_nDuration = (DWORD)m_Info.nSamplesPerFrame * nFrameCount;
  199. m_Info.nFrameSize = (int)(llSize / nFrameCount);
  200. m_Info.nBitRate = (int)((llSize * 8/ (m_nDuration / m_Info.nSamplingRate) + 500) / 1000);
  201. }
  202. else {
  203. // CBR
  204. llSize = m_Reader.GetSize();
  205. nFrameCount = int(llSize / m_Info.nFrameSize);
  206. m_nDuration = (DWORD)m_Info.nSamplesPerFrame * nFrameCount;
  207. }
  208. m_Reader.SetPointer(0, FILE_BEGIN);
  209. return TRUE;
  210. }
  211. }
  212. #endif
  213. BOOL CPlayer::MpgScanFileCompletely()
  214. {
  215. // t[SɃXL
  216. int nCount = 0;
  217. int nFrameSize = 0;
  218. int nAvgBitrate = 0;
  219. DWORD cbRead;
  220. MPEG_AUDIO_INFO infoCur, infoPrev;
  221. BYTE bBuff[MPG_SCAN_BUFF_LEN];
  222. LONGLONG llCur, llPrev;
  223. memset(&m_Info, 0, sizeof(MPEG_AUDIO_INFO));
  224. memset(&infoCur, 0, sizeof(MPEG_AUDIO_INFO));
  225. memset(&infoPrev, 0, sizeof(MPEG_AUDIO_INFO));
  226. m_Reader.SetPointer(0, FILE_BEGIN);
  227. llCur = m_Reader.ScanAudioHeader();
  228. if (llCur == MAXLONGLONG)
  229. return FALSE;
  230. llPrev = llCur;
  231. while (TRUE) {
  232. if (!m_Reader.Read(bBuff, MPG_SCAN_BUFF_LEN, &cbRead))
  233. break;
  234. if (cbRead < 4)
  235. break;
  236. if (!ParseHeader(bBuff, &infoCur)) {
  237. nCount = max(0, nCount - 1);
  238. nFrameSize -= infoPrev.nFrameSize;
  239. nAvgBitrate -= infoPrev.nBitRate;
  240. m_Reader.SetPointer(llPrev + 1, FILE_BEGIN);
  241. llCur = m_Reader.ScanAudioHeader();
  242. if (llCur == MAXLONGLONG)
  243. break;
  244. llPrev = llCur;
  245. continue;
  246. }
  247. if (nCount) {
  248. if (infoCur.nVersion != infoPrev.nVersion ||
  249. infoCur.nLayer != infoPrev.nLayer ||
  250. infoCur.nSamplingRate != infoPrev.nSamplingRate) {
  251. nCount = max(0, nCount - 1);
  252. nFrameSize -= infoPrev.nFrameSize;
  253. nAvgBitrate -= infoPrev.nBitRate;
  254. m_Reader.SetPointer(llPrev + 1, FILE_BEGIN);
  255. llCur = m_Reader.ScanAudioHeader();
  256. if (llCur == MAXLONGLONG)
  257. break;
  258. llPrev = llCur;
  259. continue;
  260. }
  261. if (nCount == 1) m_Info = infoPrev;
  262. }
  263. nCount++;
  264. nFrameSize += infoCur.nFrameSize;
  265. nAvgBitrate += infoCur.nBitRate;
  266. infoPrev = infoCur;
  267. llPrev = llCur;
  268. llCur += infoCur.nFrameSize;
  269. if (m_Reader.SetPointer(llCur, FILE_BEGIN) == MAXLONGLONG)
  270. break;
  271. }
  272. if (!nCount)
  273. return FALSE;
  274. m_Info.nFrameSize = nFrameSize / nCount; // t[TCY̕
  275. m_Info.nBitRate = (int)((double)nAvgBitrate / nCount + 0.5);
  276. m_nDuration = (DWORD)m_Info.nSamplesPerFrame * nCount;
  277. m_Reader.SetPointer(0, FILE_BEGIN);
  278. return TRUE;
  279. }
  280. BOOL CPlayer::MpgSeekFile(long lTime)
  281. {
  282. BOOL fRet = FALSE;
  283. BOOL fPause = FALSE;
  284. // Ԃ̕ϊ
  285. int nNew = (int)((double)m_Info.nSamplingRate * lTime / 1000);
  286. int nFrames = nNew / m_Info.nSamplesPerFrame;
  287. LONGLONG llOld;
  288. if (m_Options.fScanMpegCompletely) {
  289. llOld = m_Reader.SetPointer(0, FILE_BEGIN);
  290. if (m_Reader.ScanAudioHeader(m_Info.nVersion, m_Info.nLayer) != MAXLONGLONG) {
  291. int nCount = 0;
  292. BYTE bBuff[4];
  293. DWORD dwRead;
  294. while (m_Reader.Read(bBuff, sizeof(bBuff), &dwRead) && dwRead == 4) {
  295. // scan header
  296. MPEG_AUDIO_INFO info;
  297. if (ParseHeader(bBuff, &info)) {
  298. if (++nCount >= nFrames) {
  299. m_Reader.SetPointer(-4, FILE_CURRENT);
  300. fRet = TRUE;
  301. break;
  302. }
  303. else {
  304. m_Reader.SetPointer(info.nFrameSize - 4, FILE_CURRENT);
  305. }
  306. }
  307. else {
  308. m_Reader.SetPointer(-3, FILE_CURRENT);
  309. if (m_Reader.ScanAudioHeader(m_Info.nVersion, m_Info.nLayer) == MAXLONGLONG)
  310. break;
  311. }
  312. }
  313. }
  314. }
  315. else {
  316. LONGLONG llOffset = m_Info.nFrameSize * nFrames;
  317. // seek the offset
  318. llOld = m_Reader.SetPointer(llOffset, FILE_BEGIN);
  319. if (llOld != MAXLONGLONG) {
  320. if (m_Reader.ScanAudioHeader(m_Info.nVersion, m_Info.nLayer) != MAXLONGLONG)
  321. fRet = TRUE;
  322. }
  323. }
  324. if (fRet) {
  325. // V[Ň㏈
  326. m_fSeek = TRUE;
  327. m_nSeek = nNew;
  328. m_Output.Reset(); // TEhobt@̓NA
  329. }
  330. else {
  331. m_Reader.SetPointer(llOld, FILE_BEGIN);
  332. }
  333. return fRet;
  334. }
  335. int CPlayer::MpgRender(LPBYTE pbInBuf, DWORD cbInBuf, LPDWORD pcbProceed)
  336. {
  337. int nRet;
  338. BOOL fNeedOutput = FALSE;
  339. DWORD cbInput, cbOutput;
  340. *pcbProceed = 0;
  341. do {
  342. // ~tÕ`FbN
  343. if (m_fStop)
  344. return MAD_OK;
  345. // o̓obt@̊m
  346. if (!m_pOutHdr || !m_cbOutBufLeft) {
  347. if (m_pOutHdr) {
  348. OutputBuffer(m_pOutHdr, m_cbOutBuf - m_cbOutBufLeft);
  349. m_cbOutBufLeft = 0;
  350. m_pOutHdr = NULL;
  351. }
  352. m_pOutHdr = m_Output.GetBuffer();
  353. m_cbOutBufLeft = m_cbOutBuf;
  354. if (m_fSeek)
  355. return MAD_OK;
  356. if (m_fStop)
  357. return MAD_OK;
  358. }
  359. // f[^̃`FbN
  360. if (!fNeedOutput && !CheckAudioHeader(pbInBuf + *pcbProceed)) {
  361. while (++*pcbProceed < cbInBuf - 4) {
  362. MPEG_AUDIO_INFO info;
  363. if (ParseHeader(pbInBuf + *pcbProceed, &info) &&
  364. info.nVersion == m_Info.nVersion &&
  365. info.nLayer == m_Info.nLayer &&
  366. info.nSamplingRate == m_Info.nSamplingRate)
  367. break;
  368. }
  369. if (*pcbProceed > cbInBuf - 4)
  370. return MAD_NEED_MORE_INPUT;
  371. }
  372. // fR[h (1t[)
  373. nRet = m_Decoder.Decode(pbInBuf + *pcbProceed, fNeedOutput ? 0 : cbInBuf - *pcbProceed,
  374. (LPBYTE)m_pOutHdr->lpData + (m_cbOutBuf - m_cbOutBufLeft),
  375. m_cbOutBufLeft, &cbOutput, &cbInput, 16, FALSE);
  376. switch (nRet) {
  377. case MAD_FATAL_ERR:
  378. // Zbg
  379. m_Decoder.Reset();
  380. case MAD_ERR:
  381. *pcbProceed += 1; // 1oCgi߂
  382. break;
  383. case MAD_NEED_MORE_OUTPUT:
  384. fNeedOutput = TRUE;
  385. *pcbProceed += cbInput;
  386. m_cbOutBufLeft -= cbOutput;
  387. break;
  388. case MAD_OK:
  389. fNeedOutput = FALSE;
  390. *pcbProceed += cbInput;
  391. m_cbOutBufLeft -= cbOutput;
  392. break;
  393. }
  394. }
  395. while (nRet != MAD_NEED_MORE_INPUT || fNeedOutput);
  396. return nRet;
  397. }
  398. DWORD CPlayer::MpgPlayerThread()
  399. {
  400. #define MPG_FILE_READ_SIZE (MPG_FILE_BUFF_LEN * 8)
  401. BOOL fRet;
  402. BOOL fFlush = FALSE;
  403. DWORD cbBufSize, cbInBuf, cbInBufLeft = 0;
  404. LPBYTE pbRead = new BYTE[MPG_FILE_READ_SIZE];
  405. cbBufSize = MPG_FILE_READ_SIZE;
  406. if (!pbRead) {
  407. pbRead = new BYTE[MPG_FILE_BUFF_LEN];
  408. cbBufSize = MPG_FILE_BUFF_LEN;
  409. if (!pbRead) return RET_ERROR;
  410. }
  411. // fR[hJn
  412. while (TRUE) {
  413. // ~tÕ`FbN
  414. if (m_fStop) {
  415. delete [] pbRead;
  416. return RET_STOP;
  417. }
  418. {
  419. // Critical SectioñZbg
  420. CAutoLock lock(&m_csecThread);
  421. if (m_fSeek) {
  422. if (m_Status == MAP_STATUS_PLAY)
  423. m_fPlay = TRUE;
  424. m_Reverb.Reset();
  425. m_Echo.Reset();
  426. m_BassBoost.Reset();
  427. m_3DChorus.Reset();
  428. m_Output.Reset();
  429. m_Decoder.Reset();
  430. cbInBufLeft = 0;
  431. m_fSeek = FALSE;
  432. m_pOutHdr = NULL;
  433. continue;
  434. }
  435. // ǂݍ
  436. fRet = m_Reader.Read(pbRead + cbInBufLeft, cbBufSize - cbInBufLeft, &cbInBuf);
  437. if (!fRet || !cbInBuf) {
  438. if (!fRet && GetLastError() != ERROR_SUCCESS) {
  439. delete [] pbRead;
  440. return RET_ERROR;
  441. }
  442. fFlush = TRUE;
  443. }
  444. cbInBufLeft += cbInBuf;
  445. cbInBuf = 0;
  446. }
  447. if (fFlush) {
  448. if (!UnpreparePlayback(TRUE)) {
  449. fFlush = FALSE;
  450. continue;
  451. }
  452. delete [] pbRead;
  453. return RET_EOF;
  454. }
  455. if (MpgRender(pbRead, cbInBufLeft, &cbInBuf) == MAD_FATAL_ERR) {
  456. delete [] pbRead;
  457. return RET_ERROR;
  458. }
  459. if (m_fSuppress) {
  460. delete [] pbRead;
  461. return RET_EOF;
  462. }
  463. memmove(pbRead, pbRead + cbInBuf, cbInBufLeft - cbInBuf);
  464. cbInBufLeft -= cbInBuf;
  465. }
  466. }
  467. void CPlayer::MpgStop()
  468. {
  469. m_Reader.SetPointer(0, FILE_BEGIN);
  470. }
  471. void CPlayer::MpgClose()
  472. {
  473. m_Reader.Close();
  474. m_Receiver.Close();
  475. }
  476. BOOL CPlayer::MpgGetId3Tag(ID3TAGV1* pTag)
  477. {
  478. return ::GetId3Tag(m_szFile, pTag);
  479. }