mp3format.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:16k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hlxclib/string.h"
  36. #include "hlxclib/stdlib.h"
  37. #include "mp3format.h"
  38. #include "mp3queue.h"
  39. #include "mhead.h"
  40. CMp3Format::CMp3Format()
  41.  :  CAudioInfoBase(),
  42.     m_pMisc(new CMp3Misc),
  43.     m_nLayer(3),
  44.     m_bMpeg25(0),
  45.     m_bTrustPackets(FALSE),
  46.     m_pFnGetData(GetDataOffsetMPEG1)
  47. {
  48.     if (m_pMisc)
  49.         m_pMisc->SetParent(this);
  50. }
  51. CMp3Format::CMp3Format(CMp3Misc* pMisc)
  52.  :  CAudioInfoBase(),
  53.     m_pMisc(pMisc),
  54.     m_nLayer(3),
  55.     m_bMpeg25(0),
  56.     m_pFnGetData(GetDataOffsetMPEG1)
  57. {
  58.     if (m_pMisc)
  59.         m_pMisc->SetParent(this);
  60. }
  61. CMp3Format::~CMp3Format()
  62. {
  63.     HX_DELETE(m_pMisc);
  64. }
  65. BOOL CMp3Format::Init(UINT8 *pHeader,
  66.                       UINT32 ulSize)
  67. {
  68.     MPEG_HEAD h;
  69.     memset(&h, 0, sizeof(h));
  70.     if (!head_info(pHeader, ulSize, &h, m_bTrustPackets))
  71.         return 0;
  72.     // Detect MPEG2.5
  73.     if ((pHeader[1] & 0xF0) == 0xE0)
  74.         m_bMpeg25 = 1;
  75.     // Detect MPEG1/MPEG2
  76.     if(h.id)
  77.         m_pFnGetData = GetDataOffsetMPEG1;
  78.     else
  79.         m_pFnGetData = GetDataOffsetMPEG2;
  80.     m_ySyncWord = pHeader[1];
  81.     UINT32   ulTemp;
  82.     int      nTemp;
  83.     GetEncodeInfo(pHeader,
  84.                   ulSize,
  85.                   ulTemp,
  86.                   ulTemp,
  87.                   nTemp,
  88.                   m_nLayer,
  89.                   nTemp);
  90.     
  91.     m_bIsInited = 1;
  92.     return 1;
  93. }
  94. BOOL CMp3Format::GetDataOffset(UINT8 *pHeader,
  95.                                UINT32 dwSize,
  96.                                int &nFrameSize,
  97.                                int &nHeaderSize,
  98.                                int &nDataOffset)
  99. {
  100.     return m_pFnGetData(pHeader, dwSize, nFrameSize, nHeaderSize, nDataOffset, m_bTrustPackets);
  101. }
  102. void CMp3Format::ClearMainDataBegin(UINT8 *pHeader)
  103. {
  104.     if (m_nLayer != 3)
  105.         return;
  106.     int nOffset = 4;
  107.     // Check protection bit
  108.     if ((pHeader[1] & 1) == 0)
  109.         nOffset += 2;
  110.     // MPEG1 main_data_begin is 9 bits in MPEG2 it is 8
  111.     pHeader[nOffset] = 0;
  112.     
  113.     if (GetDataOffsetMPEG1 == m_pFnGetData)
  114.         pHeader[nOffset + 1] &= 0x7F;
  115. }
  116. BOOL CMp3Format::GetEncodeInfo(UINT8 *pHeader,
  117.                                UINT32 dwSize,
  118.                                UINT32 &ulBitRate,
  119.                                UINT32 &ulSampleRate,
  120.                                int &nChannels,
  121.                                int &nLayer,
  122.                                int &nSamplesPerFrame)
  123. {
  124.     MPEG_HEAD h;
  125.     INT32 aSampRate[2][3] =         // MPEG SPEC x NATIVE RATE
  126.     {
  127.         22050,24000,16000,     // MPEG2
  128.         44100,48000,32000      // MPEG1
  129.     };
  130.     memset(&h, 0, sizeof(h));
  131.     ulBitRate =
  132.     ulSampleRate = 0;
  133.     nChannels =
  134.     nSamplesPerFrame = 0;
  135.     int nBitRate = 0;
  136.     if (!head_info2(pHeader, dwSize, &h, &nBitRate, m_bTrustPackets))
  137.     {
  138.         ulBitRate = nBitRate;
  139.         return 0;
  140.     }
  141.     ulBitRate = nBitRate;
  142.     
  143.     if (3 == h.mode)
  144.         nChannels = 1;
  145.     else
  146.         nChannels = 2;
  147.     ulSampleRate = aSampRate[h.id][h.sr_index] >> m_bMpeg25;
  148.     // Get the layer so we can work out the bit rate
  149.     switch (h.option)
  150.     {
  151.         case 3:
  152.             nLayer = 1;
  153.             break;
  154.     
  155.         case 2:
  156.             nLayer = 2;
  157.             break;
  158.     
  159.         case 1:
  160.             nLayer = 3;
  161.     }
  162.     
  163.     if((h.option == 1) & (h.id == 0))  // MPEGII Layer III
  164.     {
  165.         nSamplesPerFrame = 576;
  166.         m_pFnGetData = GetDataOffsetMPEG2;
  167.     }
  168.     else if(h.option == 3)
  169.         nSamplesPerFrame = 384;     // Layer I
  170.     else
  171.         nSamplesPerFrame = 1152;
  172.     return 1;
  173. }
  174. int CMp3Format::ReformatMP3Frame(UINT8 **ppFrame,
  175.                                  UINT32 dwBytes,
  176.                                  UINT32 dwPrevBytes)
  177. {
  178.     // Get the sync info
  179.     int nFrameSize = 0,
  180.         nHeaderSize = 0,
  181.         nDataOffset = 0;
  182.     UINT8   bAcceptFrame = 1;
  183.     UINT8   *pFrame = *ppFrame;
  184.     if (!GetDataOffset(pFrame,
  185.                        dwBytes,
  186.                        nFrameSize,
  187.                        nHeaderSize,
  188.                        nDataOffset))
  189.         return 0;
  190.     if (m_nLayer != 3)
  191.         return nFrameSize;
  192.     // nDataOffset points to data before our buffer.
  193.     // We must reformat what we can for the next frame.
  194.     if ((UINT32)nDataOffset > dwPrevBytes)
  195.     {
  196.         nDataOffset = dwPrevBytes;
  197.         bAcceptFrame = 0;
  198.     }
  199.     // Calculate the modified frame size
  200.     UINT8 *pNextFrame = pFrame + nFrameSize;
  201.     int nDataOffset2 = 0,
  202.         nTemp = 0;
  203.     
  204.     // Last frame has just enough data   
  205.     if ((int)dwBytes > nFrameSize)   
  206.     {     
  207.         if (!GetDataOffset(pNextFrame,
  208.                            dwBytes - nFrameSize,
  209.                            nTemp,
  210.                            nTemp,
  211.                            nDataOffset2))
  212.             return 0;
  213.     }
  214.     // If this is a self contained frame, do nothing special
  215.     if (!nDataOffset && !nDataOffset2)
  216.         return nFrameSize;
  217.     // Clear main_data_begin offset of current sync
  218.     nTemp = 4;
  219.     // Check protection bit
  220.     if ((pFrame[1] & 1) == 0)
  221.         nTemp += 2;
  222.     //pFrame[nTemp] = 0;
  223.     //
  224.     // MPEG1 main_data_begin is 9 bits in MPEG2 it is 8
  225.     //if (GetDataOffsetMPEG1 == m_pFnGetData)
  226.     //    pFrame[nTemp + 1] &= 0x7F;
  227.     // Store the header of current sync
  228.     UINT8 *pHeader = new UINT8[nHeaderSize];
  229.     memcpy(pHeader, pFrame, nHeaderSize); /* Flawfinder: ignore */
  230.     // Move offset data forward
  231.     memmove(pFrame - nDataOffset + nHeaderSize,
  232.             pFrame - nDataOffset,
  233.             nDataOffset);
  234.     // Copy header data before offset data
  235.     memcpy(pFrame - nDataOffset, /* Flawfinder: ignore */
  236.            pHeader,
  237.            nHeaderSize);
  238.     delete [] pHeader;
  239.     *ppFrame -= nDataOffset;
  240.     // Calculate the new frame size
  241.     nFrameSize = (pNextFrame - nDataOffset2) -
  242.                  *ppFrame;
  243.     return nFrameSize * bAcceptFrame;
  244. }
  245. int CMp3Format::CheckValidFrame(UINT8 *pBuf,
  246.                                 UINT32 dwSize)
  247. {
  248.     // Are there enough bytes
  249.     if (dwSize < 4)
  250.         return 0;
  251.     // Is this a sync word
  252.     if ((pBuf[0] != 0xFF) |
  253.         !IsValidSyncWord(pBuf[1]))
  254.         return 0;
  255.     
  256.     MPEG_HEAD       head;
  257.     memset(&head, 0, sizeof(head));
  258.     int nRet = head_info(pBuf, dwSize, &head, m_bTrustPackets);
  259.     if (nRet)
  260.     {
  261.         nRet += head.pad;
  262.         if (nRet > (int)dwSize)
  263.             nRet = 0;
  264.     }
  265.     return nRet;
  266. }
  267. int CMp3Format::UnformatMP3Frame(CMp3Queue* pQueue,
  268.                                  UINT8* pDest,
  269.                                  UINT32 &ulTime)
  270. {
  271.     tFrameInfo* pInfo = pQueue->GetHead();
  272.     ulTime = pInfo->ulTime;
  273.     // Do we have enough bytes for the frame
  274.     if (pInfo->ulFrameSize - pInfo->ulHdrSize <= pQueue->GetDataBytes())
  275.     {
  276.         int nFrameSize = pInfo->ulFrameSize,
  277.             nRet = pInfo->ulFrameSize;
  278.         memcpy(pDest, pInfo->pHdr, pInfo->ulHdrSize); /* Flawfinder: ignore */
  279.         pDest += pInfo->ulHdrSize;
  280.         memcpy(pDest, pInfo->pData, pInfo->ulDataSize); /* Flawfinder: ignore */
  281.         nFrameSize -= pInfo->ulDataSize + pInfo->ulHdrSize;
  282.         pQueue->RemoveDataBytes(pInfo->ulDataSize);
  283.         pInfo->pData += pInfo->ulDataSize;
  284.         pDest += pInfo->ulDataSize;
  285.         pInfo->ulDataSize = 0;
  286.         int nCopy;
  287.         // Copy data from future frames until we comple this frame
  288.         while (nFrameSize)
  289.         {
  290.             pInfo = pQueue->Next();
  291.             nCopy = min(pInfo->ulDataSize, (UINT32)nFrameSize);
  292.             memcpy(pDest, pInfo->pData, nCopy); /* Flawfinder: ignore */
  293.             pDest += nCopy;
  294.             pInfo->pData += nCopy;
  295.             pInfo->ulDataSize -= nCopy;
  296.             nFrameSize -= nCopy;
  297.             pQueue->RemoveDataBytes(nCopy);
  298.         }
  299.         pQueue->RemoveHead();
  300.         return nRet;
  301.     }
  302.     else
  303.         return 0;
  304. }
  305. INT32 CMp3Format::ScanForSyncWord(UINT8 *pBuf,
  306.                                   INT32 lSize,
  307.                                   int &nFrameSize)
  308. {
  309.     UINT8       *pStart = pBuf,
  310.                 *pEnd = pBuf + lSize - 4,
  311.                 *pTemp = NULL,
  312.                 ySyncCheck = 0;
  313.     MPEG_HEAD   head;
  314.     int         iFrameSize = 0;
  315.     if (lSize < 4)
  316.         return -1;
  317.     nFrameSize = 0;
  318.     for (; pBuf < pEnd; pBuf++)
  319.     {
  320.         if (pBuf[0] != 0xFF)
  321.             continue;
  322.             
  323.         if (m_ySyncWord)
  324.         {
  325.             if (!IsValidSyncWord(pBuf[1]))
  326.                 continue;
  327.         }
  328.         else if ((pBuf[1] & 0xE0) != 0xE0)
  329.             continue;
  330.         ySyncCheck = pBuf[1];
  331.         memset(&head, 0, sizeof(head));
  332.         iFrameSize = head_info(pBuf, pEnd-pBuf, &head, m_bTrustPackets);
  333.         // Looks like a valid frame
  334.         if (iFrameSize)
  335.         {
  336.             iFrameSize += head.pad;
  337.             // Check for another frame
  338.             if (pBuf+iFrameSize < pEnd+3)
  339.             {
  340.                 pTemp = pBuf + iFrameSize;
  341.                 // We do not have consequitve frames..what to do, what to do?
  342.                 if ((pTemp[0] != 0xFF) |
  343.                     (pTemp[1] != ySyncCheck))
  344.                 {
  345.                     INT32 lHeaderSize = 0;
  346.                     // First, check for know non-mp3 data that may
  347.                     // reside in an mp3 stream and terminate a frame.
  348.                     BOOL bFoundHdr = FALSE;
  349.                     
  350.                     if (m_pMisc)
  351.                         bFoundHdr = m_pMisc->CheckForHeaders(pTemp,
  352.                                                              pEnd-pTemp+4,
  353.                                                              lHeaderSize);
  354.                     if (bFoundHdr)
  355.                         nFrameSize = iFrameSize;
  356.                     // Next, check if the padding bit was incorrectly set 
  357.                     else if ((pTemp[-1] == 0xFF) &
  358.                              (pTemp[0] == ySyncCheck))
  359.                         nFrameSize = iFrameSize;
  360.                     // Finally, check if the padding bit was not set and
  361.                     // should have been.
  362.                     else if ((pTemp[1] == 0xFF) &
  363.                              (pTemp[2] == ySyncCheck))
  364.                         nFrameSize = iFrameSize;
  365.                     // Did not find consequtive frames.  Keep looking
  366.                     else
  367.                         continue;
  368.                 }
  369.                 else
  370.                 {
  371.                     // We found a frame
  372.                     nFrameSize = iFrameSize;
  373.                 }
  374.             }
  375.             // There is one full frame in this buffer
  376.             else if (pBuf+iFrameSize == pEnd+4)
  377.             {
  378.                 // We found a frame
  379.                 nFrameSize = iFrameSize;             
  380.             }
  381.             break;
  382.         }
  383.     }                                                                      
  384.     if (nFrameSize)
  385.         return pBuf - pStart;
  386.     else
  387.         return -1;
  388. }
  389. BOOL CMp3Format::CheckForHeaders(UINT8 *pBuf,
  390.                                  UINT32 dwSize,
  391.                                  INT32 &lHeaderSize)  
  392. {
  393.     if (m_pMisc)
  394.         return m_pMisc->CheckForHeaders(pBuf, dwSize, lHeaderSize);
  395.     else
  396.         return FALSE;
  397. }
  398. eHeaderType CMp3Format::GetHeaderType()
  399. {
  400.     if (m_pMisc)
  401.         return m_pMisc->GetHeaderType();
  402.     else
  403.         return eNone;
  404. }
  405. // Functions to access the Id3 header values
  406. UINT8* CMp3Format::GetId3Title(int &nLen)
  407. {
  408.     if (m_pMisc)
  409.         return m_pMisc->GetId3Title(nLen);
  410.     else
  411.         return NULL;
  412. }
  413. UINT8* CMp3Format::GetId3Artist(int &nLen)
  414. {
  415.     if (m_pMisc)
  416.         return m_pMisc->GetId3Artist(nLen);
  417.     else
  418.         return NULL;
  419. }
  420. UINT8* CMp3Format::GetId3Album(int &nLen)
  421. {
  422.     if (m_pMisc)
  423.         return m_pMisc->GetId3Album(nLen);
  424.     else
  425.         return NULL;
  426. }
  427. UINT8* CMp3Format::GetId3Genre(int &nLen)
  428. {
  429.     if (m_pMisc)
  430.         return m_pMisc->GetId3Genre(nLen);
  431.     else
  432.         return NULL;
  433. }
  434. int CMp3Format::GetMetaOffset()
  435. {
  436.     if (m_pMisc)
  437.         return m_pMisc->GetMetaOffset();
  438.     else
  439.         return 0;
  440. }
  441. int CMp3Format::GetMetaRepeat()
  442. {
  443.     if (m_pMisc)
  444.         return m_pMisc->GetMetaRepeat();
  445.     else
  446.         return 0;
  447. }
  448. ///////////////////////////////////////////////////////////////////////////////
  449. // Private Functions
  450. BOOL CMp3Format::GetDataOffsetMPEG1(UINT8 *pHeader,
  451.                                     UINT32 dwSize,
  452.                                     int &nFrameSize,
  453.                                     int &nHeaderSize,
  454.                                     int &nDataOffset,
  455.                                     int trustPackets)
  456. {
  457.     // Get header info
  458.     MPEG_HEAD h;
  459.     memset(&h, 0, sizeof(h));
  460.     nFrameSize = head_info(pHeader, dwSize, &h, trustPackets);
  461.     
  462.     if (nFrameSize)
  463.         nFrameSize += h.pad;
  464.     // HeaderSize is the sync word, CRC, and side info
  465.     nHeaderSize = 4;
  466.     // Check protection bit
  467.     if ((pHeader[1] & 1) == 0)
  468.         nHeaderSize += 2;
  469.     // Not enough data to check main_data_begin
  470.     if (dwSize < (unsigned int)nHeaderSize + 2)
  471.         return 0;
  472.     // Extract main_data_begin offset (9 bits)
  473.     nDataOffset = (pHeader[nHeaderSize] << 1) +
  474.                   (pHeader[nHeaderSize + 1] >> 7);
  475.     // Side info (256 bits for stereo, 136 for mono)
  476.     if (3 == h.mode)
  477.         nHeaderSize += 17;
  478.     else
  479.         nHeaderSize += 32;
  480.     return 1;
  481. }
  482. BOOL CMp3Format::GetDataOffsetMPEG2(UINT8 *pHeader,
  483.                                     UINT32 dwSize,
  484.                                     int &nFrameSize,
  485.                                     int &nHeaderSize,
  486.                                     int &nDataOffset,
  487.                                     int trustPackets)
  488. {
  489.     // Get header info
  490.     MPEG_HEAD h;
  491.     memset(&h, 0, sizeof(h));
  492.     nFrameSize = head_info(pHeader, dwSize, &h, trustPackets);
  493.     
  494.     if (nFrameSize)
  495.         nFrameSize += h.pad;
  496.     // HeaderSize is the sync word, CRC, and side info
  497.     nHeaderSize = 4;
  498.     // Check protection bit
  499.     if ((pHeader[1] & 1) == 0)
  500.         nHeaderSize += 2;
  501.     // Not enough data to check main_data_begin
  502.     if (dwSize < (unsigned int)nHeaderSize + 1)
  503.         return 0;
  504.     // Extract main_data_begin offset (8 bits)
  505.     nDataOffset = pHeader[nHeaderSize];
  506.     // Side info (136 bits for stereo, 72 for mono)
  507.     if (3 == h.mode)
  508.         nHeaderSize += 9;
  509.     else
  510.         nHeaderSize += 17;
  511.     return 1;
  512. }