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

📄 pmp3_dec.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*
File    : \Audio\MP3Dec\
Desc    : MP3解码。

Author  : FSH , Vincent Hisung
Date    : 2007-08-xx
Notes   :

$Log    :
* FSH                     2007/06/01    建立此文件
*
* vincent                 2007/08/xx
*
*/
/****************************************************************/

#include "../include/audio_globals.h"
#include "../include/CommonCmd.h"

#include "MP3DEC_MP3Dec.h"
#include "MP3DEC_pMP3_Dec.h"

#include "../include/file_access.h"

static  int bitstreamDataToProcess;
static  int buffer_size;

static  long OutLength;

int         sp, bt;
int         FirstHeaderDecoded = 0;

//extern int Codec_Samples_Num;
extern DecoderList AudioDecoders[];
extern stID3V2XInfoType ID3V2XInfo;
extern int GetHeaderPosition(tMP3 *);

//****************************************************************************
//
// FillBitstream
//
//****************************************************************************
//填充位流,由解码器适时调用
void FillBitstream(tMP3 *pMP3, int mtest)
{
    int bytesCurrent;
    int bytesNeeded;
    char *bsdata;

    int result_fread = 0;

    bytesCurrent = pMP3->bitstream.dataLength - pMP3->bitstream.dataOffset;
    bytesNeeded  = pMP3->bitstream.dataRequired - bytesCurrent;

    /* Update bitstream structure values */
    pMP3->bitstream.data       += pMP3->bitstream.dataOffset;
    pMP3->bitstream.dataOffset = 0;
    pMP3->bitstream.dataLength = bytesCurrent;

    /* bsdata is the address at which to start writing new data */
    bsdata = pMP3->bitstream.data + bytesCurrent;

    if (bytesNeeded > 0)
    {
        if (((pMP3->bitstream.data - pENCODED_DATA) + pMP3->bitstream.dataRequired) > buffer_size)
        {
            memcpy(pENCODED_DATA, pMP3->bitstream.data, bytesCurrent);

            pMP3->bitstream.data = pENCODED_DATA;
            bsdata = pENCODED_DATA + bytesCurrent;
        }
        result_fread = RKFIO_FRead(pRawFileCache, bsdata,   bytesNeeded);

        bsdata = bsdata + result_fread;

        if (result_fread < bytesNeeded)
        {
            bitstreamDataToProcess = 0;
        }

        pMP3->bitstream.dataLength = bsdata - pMP3->bitstream.data;

        // If there is insufficient data, signal end of file
        if (pMP3->bitstream.dataLength < pMP3->bitstream.dataRequired)
        {
            bitstreamDataToProcess = 0;
        }

    }
}


//MP3解码器SEEK函数,由解码器调用,用户无需调用
static eDecoderStatus Seek(int skipvalue, int skiptype, tMP3 *pMP3, unsigned long ulPos, int File)
{
    eDecoderStatus status;
    int result;

    /* Update bitstream structure before jump */
    pMP3->bitstream.dataLength -= pMP3->bitstream.dataOffset;
    pMP3->bitstream.data += pMP3->bitstream.dataOffset;
    pMP3->bitstream.dataOffset = 0;

    if (skiptype == SEEK_BY_BYTES)
    {
        while (
            kDecoderStatus_MoreData == (status = pMP3->workspace->Decoder->BitstreamSeekBytes(skipvalue,
                                                 pMP3->workspace->handle,
                                                 pMP3->workspace->scratch,
                                                 &(pMP3->bitstream)))
            && bitstreamDataToProcess
        )
        {
            FillBitstream(pMP3, File);
        }
    }
    else if (skiptype == SEEK_BY_TIME)
    {
        while (
            kDecoderStatus_MoreData == (status = pMP3->workspace->Decoder->BitstreamSeekTime(skipvalue,
                                                 pMP3->workspace->handle,
                                                 pMP3->workspace->scratch,
                                                 &(pMP3->bitstream)))
            && bitstreamDataToProcess
        )
        {
            FillBitstream(pMP3, File);
        }
    }
    else
    {
        return(kDecoderStatus_InvalidArgument);
    }

    if (status == kDecoderStatus_NoError)
    {
        /* Move along bitstream by the amount specified in dataOffset */
        result = RKFIO_FSeek(pRawFileCache, ulPos, 0);
        if (result < 0)
        {
            status = kDecoderStatus_Fseek_Error;
        }

        /* Flush all data - none of it is valid anymore */
        memset(pENCODED_DATA, 0, buffer_size);
        pMP3->bitstream.data = pENCODED_DATA;
        pMP3->bitstream.dataOffset = 0;
        pMP3->bitstream.dataLength = 0;
        pMP3->bitstream.frameRemain = 0;
        pMP3->bitstream.dataRequired = pMP3->workspace->requirements->maxInputSize;
    }
    else
    {
        return status;
    }
    return status;
}


//****************************************************************************
//
// The codec plug-in entry point for the MP3 decoder.
//
//****************************************************************************
//功能实现情况:
//SUBFN_CODEC_GETNAME  :   不支持
//SUBFN_CODEC_GETARTIST:   不支持
//SUBFN_CODEC_GETTITLE :   不支持
//SUBFN_CODEC_GETBITRATE:  得到码率
//SUBFN_CODEC_GETSAMPLERATE: 得到采样率
//SUBFN_CODEC_GETCHANNELS: 得到声道数目
//SUBFN_CODEC_GETLENGTH :  得到时长 [单位:毫秒]
//SUBFN_CODEC_GETTIME  :   得到当前播放时间 [单位:毫秒]
//SUBFN_CODEC_OPEN_DEC :   打开解码器(初始化)
//SUBFN_CODEC_DECODE   :   解码
//SUBFN_CODEC_ENCODE   :   不支持
//SUBFN_CODEC_SEEK     :   按时间直接定位 [单位:毫秒]
//SUBFN_CODEC_CLOSE    :   关闭解码器
/******************************************************
Name:  MP3DecFunction
Desc:  MP3解码器接口函数
Param: ulIoctl 子功能号
    ulParam1 子功能参数1
    ulParam2 子功能参数2
    ulParam3 子功能参数3
    ulParam4 子功能参数4

Return: 0-失败 1-成功
Global: 无
Note: 无
Author: FSH
Log:
******************************************************/
int CountToSkip;
int ConntTest;
int OkDecoder;

#define   SKIPBYTESIZE 150

unsigned long
MP3Function(unsigned long ulSubFn, unsigned long ulParam1, unsigned long ulParam2,
            unsigned long ulParam3, unsigned long ulParam4)
{
    unsigned int WaitCounter = 0;

    switch (ulSubFn)
    {
        case SUBFN_CODEC_GETCAPTUREBUFFER:
            {
                tMP3 *pMP3;

                // The first parameter is a pointer to the MP3 persistent state.
                pMP3 = (tMP3 *)ulParam1;


                *(unsigned long *)ulParam2 = (unsigned long) pMP3->psLeft ;
                *(unsigned long *)ulParam3 = (unsigned long) pMP3->psRight;
                *(unsigned long *)ulParam4 = (unsigned long) OutLength ;

                return(1);
            }

            // Decode a frame of data.
        case SUBFN_CODEC_DECODE:
            {
                OutLength = 1152;

                if (bitstreamDataToProcess != 0)
                {
                    tMP3 *pMP3;
                    short *psLeft, *psRight;
                    long lLength;

                    pMP3 = (tMP3 *)ulParam1;

                    pMP3->status = 0;

                    if (FirstHeaderDecoded != 1)
                    {
                        //bitstreamDataToProcess = -1;
                        do
                        {
                            FillBitstream(pMP3, 0);

                            if (!bitstreamDataToProcess) break;

                            pMP3->status = pMP3->workspace->Decoder->DecodeHeader(pMP3->workspace->handle,
                                           pMP3->workspace->scratch,
                                           &(pMP3->bitstream));

                            //////////////////////////////////////////////////////////

                            if (pMP3->status != kDecoderStatus_NoError)
                            {
                                CountToSkip++;
                                ConntTest++;
                            }

                            if (ConntTest > 40000)
                            {
                                bitstreamDataToProcess = 0;
                                return 0;
                            }

                            if (CountToSkip >= SKIPBYTESIZE)
                            {
                                //bitstreamDataToProcess = 0;
                                pMP3->status = kDecoderStatus_NoError;
                                memset(pMP3->psLeft, 0, MP3_PCM_BUFFER_SIZE);
                                memset(pMP3->psRight, 0, MP3_PCM_BUFFER_SIZE);
                                pMP3->ulTimePos += 1152;
                                CountToSkip = 0;
                                OkDecoder = 0;
                                return 1;
                            }




                            /////////////////////////////////////////////////////////
                            /*
                                              if(pMP3->bitstream.sampleRate != sp)
                                              {
                                                  pMP3->status = kDecoderStatus_ReservedSamplingFrequency;
                                              }
                                              */
                        }

                        //???? added by Vincent
                        while ((pMP3->status != kDecoderStatus_NoError) && bitstreamDataToProcess);

                        if (pMP3->status != kDecoderStatus_NoError)
                        {
                            //解码出错
                            goto return_decode; //return(0);
                        }
                    }

                    //decode header
                    FirstHeaderDecoded = 0;

                    if (!bitstreamDataToProcess) goto return_decode; //return(0);

                    pMP3->bitstream.formats.outputFormats = OUTPUT_FORMAT_16BIT;

                    pMP3->output.channels[0] = pMP3->psLeft;   //    psLeft;
                    pMP3->output.channels[1] = pMP3->psRight;   //  psRight;

                    bitstreamDataToProcess = -1;

                    do
                    {
                        if (pMP3->status == kDecoderStatus_FrameDiscarded || pMP3->status == kDecoderStatus_BrokenFrame)
                        {
                            bitstreamDataToProcess = -1;
                            do
                            {
                                FillBitstream(pMP3, 0);

                                if (!bitstreamDataToProcess) break;
                                pMP3->status = pMP3->workspace->Decoder->DecodeHeader(pMP3->workspace->handle,
                                               pMP3->workspace->scratch,
                                               &(pMP3->bitstream));
                                //////////////////////////////////////////////////////////



                                if (pMP3->status != kDecoderStatus_NoError)
                                {
                                    CountToSkip++;
                                    ConntTest++;
                                }

                                if (ConntTest > 40000)
                                {
                                    bitstreamDataToProcess = 0;
                                    return 0;
                                }

                                if (CountToSkip >= SKIPBYTESIZE)
                                {
                                    pMP3->status = kDecoderStatus_NoError;
                                    memset(pMP3->psLeft, 0, MP3_PCM_BUFFER_SIZE);
                                    memset(pMP3->psRight, 0, MP3_PCM_BUFFER_SIZE);
                                    pMP3->ulTimePos += 1152;
                                    CountToSkip = 0;
                                    OkDecoder = 0;
                                    return 1;
                                }

                                /////////////////////////////////////////////////////////

                                /*
                                                     if(pMP3->bitstream.sampleRate != sp)
                                                     {
                                                         pMP3->status = kDecoderStatus_ReservedSamplingFrequency;
                                                     }
                                                     */

                            }
                            while ((pMP3->status != kDecoderStatus_NoError && bitstreamDataToProcess));
                        }

                        if (pMP3->status != kDecoderStatus_NoError)
                        {
                            goto return_decode; //return(0);
                        }

                        FillBitstream(pMP3, 0);
                        if (!bitstreamDataToProcess)
                        {
                            break;
                        }

                        pMP3->status = pMP3->workspace->Decoder->DecodeFrame(pMP3->workspace->handle,
                                       pMP3->workspace->scratch,
                                       &(pMP3->output),
                                       &(pMP3->bitstream));
                    }

                    //???? by Vincent
                    while (pMP3->status == kDecoderStatus_MoreSamples ||
                            (pMP3->status == kDecoderStatus_MoreData && bitstreamDataToProcess) ||
                            pMP3->status != kDecoderStatus_NoError);

                    CountToSkip = 0;
                    ConntTest = 0;






                    if (!bitstreamDataToProcess) goto return_decode;

                    if (pMP3->status != kDecoderStatus_NoError)
                    {
                        goto return_decode;
                    }

⌨️ 快捷键说明

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