📄 pmp3_dec.c
字号:
/* 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 + -