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

📄 mp3format.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

#include "hlxclib/string.h"
#include "hlxclib/stdlib.h"
#include "mp3format.h"
#include "mp3queue.h"
#include "mhead.h"

CMp3Format::CMp3Format()
 :  CAudioInfoBase(),
    m_pMisc(new CMp3Misc),
    m_nLayer(3),
    m_bMpeg25(0),
    m_bTrustPackets(FALSE),
    m_pFnGetData(GetDataOffsetMPEG1)
{
    if (m_pMisc)
        m_pMisc->SetParent(this);
}

CMp3Format::CMp3Format(CMp3Misc* pMisc)
 :  CAudioInfoBase(),
    m_pMisc(pMisc),
    m_nLayer(3),
    m_bMpeg25(0),
    m_pFnGetData(GetDataOffsetMPEG1)
{
    if (m_pMisc)
        m_pMisc->SetParent(this);
}

CMp3Format::~CMp3Format()
{
    HX_DELETE(m_pMisc);
}

BOOL CMp3Format::Init(UINT8 *pHeader,
                      UINT32 ulSize)
{
    MPEG_HEAD h;
    memset(&h, 0, sizeof(h));

    if (!head_info(pHeader, ulSize, &h, m_bTrustPackets))
        return 0;

    // Detect MPEG2.5
    if ((pHeader[1] & 0xF0) == 0xE0)
        m_bMpeg25 = 1;

    // Detect MPEG1/MPEG2
    if(h.id)
        m_pFnGetData = GetDataOffsetMPEG1;
    else
        m_pFnGetData = GetDataOffsetMPEG2;

    m_ySyncWord = pHeader[1];

    UINT32   ulTemp;
    int      nTemp;
    GetEncodeInfo(pHeader,
                  ulSize,
                  ulTemp,
                  ulTemp,
                  nTemp,
                  m_nLayer,
                  nTemp);
    
    m_bIsInited = 1;

    return 1;
}

BOOL CMp3Format::GetDataOffset(UINT8 *pHeader,
                               UINT32 dwSize,
                               int &nFrameSize,
                               int &nHeaderSize,
                               int &nDataOffset)
{
    return m_pFnGetData(pHeader, dwSize, nFrameSize, nHeaderSize, nDataOffset, m_bTrustPackets);
}

void CMp3Format::ClearMainDataBegin(UINT8 *pHeader)
{
    if (m_nLayer != 3)
        return;

    int nOffset = 4;

    // Check protection bit
    if ((pHeader[1] & 1) == 0)
        nOffset += 2;

    // MPEG1 main_data_begin is 9 bits in MPEG2 it is 8
    pHeader[nOffset] = 0;
    
    if (GetDataOffsetMPEG1 == m_pFnGetData)
        pHeader[nOffset + 1] &= 0x7F;
}

BOOL CMp3Format::GetEncodeInfo(UINT8 *pHeader,
                               UINT32 dwSize,
                               UINT32 &ulBitRate,
                               UINT32 &ulSampleRate,
                               int &nChannels,
                               int &nLayer,
                               int &nSamplesPerFrame)
{
    MPEG_HEAD h;
    INT32 aSampRate[2][3] =         // MPEG SPEC x NATIVE RATE
    {
        22050,24000,16000,     // MPEG2
        44100,48000,32000      // MPEG1
    };

    memset(&h, 0, sizeof(h));

    ulBitRate =
    ulSampleRate = 0;

    nChannels =
    nSamplesPerFrame = 0;

    int nBitRate = 0;
    if (!head_info2(pHeader, dwSize, &h, &nBitRate, m_bTrustPackets))
    {
        ulBitRate = nBitRate;
        return 0;
    }

    ulBitRate = nBitRate;
    
    if (3 == h.mode)
        nChannels = 1;
    else
        nChannels = 2;

    ulSampleRate = aSampRate[h.id][h.sr_index] >> m_bMpeg25;

    // Get the layer so we can work out the bit rate
    switch (h.option)
    {
        case 3:
            nLayer = 1;
            break;
    
        case 2:
            nLayer = 2;
            break;
    
        case 1:
            nLayer = 3;
    }
    
    if((h.option == 1) & (h.id == 0))  // MPEGII Layer III
    {
        nSamplesPerFrame = 576;
        m_pFnGetData = GetDataOffsetMPEG2;
    }
    else if(h.option == 3)
        nSamplesPerFrame = 384;     // Layer I
    else
        nSamplesPerFrame = 1152;

    return 1;
}

int CMp3Format::ReformatMP3Frame(UINT8 **ppFrame,
                                 UINT32 dwBytes,
                                 UINT32 dwPrevBytes)
{
    // Get the sync info
    int nFrameSize = 0,
        nHeaderSize = 0,
        nDataOffset = 0;

    UINT8   bAcceptFrame = 1;
    UINT8   *pFrame = *ppFrame;

    if (!GetDataOffset(pFrame,
                       dwBytes,
                       nFrameSize,
                       nHeaderSize,
                       nDataOffset))
        return 0;

    if (m_nLayer != 3)
        return nFrameSize;

    // nDataOffset points to data before our buffer.
    // We must reformat what we can for the next frame.
    if ((UINT32)nDataOffset > dwPrevBytes)
    {
        nDataOffset = dwPrevBytes;
        bAcceptFrame = 0;
    }

    // Calculate the modified frame size
    UINT8 *pNextFrame = pFrame + nFrameSize;
    int nDataOffset2 = 0,
        nTemp = 0;
    
    // Last frame has just enough data   
    if ((int)dwBytes > nFrameSize)   
    {     
        if (!GetDataOffset(pNextFrame,
                           dwBytes - nFrameSize,
                           nTemp,
                           nTemp,
                           nDataOffset2))
            return 0;
    }

    // If this is a self contained frame, do nothing special
    if (!nDataOffset && !nDataOffset2)
        return nFrameSize;

    // Clear main_data_begin offset of current sync
    nTemp = 4;

    // Check protection bit
    if ((pFrame[1] & 1) == 0)
        nTemp += 2;

    //pFrame[nTemp] = 0;
    //
    // MPEG1 main_data_begin is 9 bits in MPEG2 it is 8
    //if (GetDataOffsetMPEG1 == m_pFnGetData)
    //    pFrame[nTemp + 1] &= 0x7F;

    // Store the header of current sync
    UINT8 *pHeader = new UINT8[nHeaderSize];

    memcpy(pHeader, pFrame, nHeaderSize); /* Flawfinder: ignore */

    // Move offset data forward
    memmove(pFrame - nDataOffset + nHeaderSize,
            pFrame - nDataOffset,
            nDataOffset);

    // Copy header data before offset data
    memcpy(pFrame - nDataOffset, /* Flawfinder: ignore */
           pHeader,
           nHeaderSize);

    delete [] pHeader;

    *ppFrame -= nDataOffset;

    // Calculate the new frame size
    nFrameSize = (pNextFrame - nDataOffset2) -
                 *ppFrame;
    return nFrameSize * bAcceptFrame;

}


int CMp3Format::CheckValidFrame(UINT8 *pBuf,
                                UINT32 dwSize)
{
    // Are there enough bytes
    if (dwSize < 4)
        return 0;

    // Is this a sync word
    if ((pBuf[0] != 0xFF) |
        !IsValidSyncWord(pBuf[1]))
        return 0;
    
    MPEG_HEAD       head;
    memset(&head, 0, sizeof(head));

    int nRet = head_info(pBuf, dwSize, &head, m_bTrustPackets);

    if (nRet)
    {

⌨️ 快捷键说明

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