1. decode data is always PCM16.
2. aac codec can receive any frame data, but eaac+ decode must give it data with full frame.
so you need only transfer full frame data to it.
I research aac format, and do a little decode, which judge full frame edge.
Code:
TBool CAacCodec::DecodeAudio(const TDesC8& aSrc, TDes8& aDest)
{
//FUNC_U_TRACE();
TPtr8 pSrc(0, 0, 0);
if ( iRemainData.Length() <= 0 )
{
pSrc.Set((TUint8*)aSrc.Ptr(), aSrc.Length(), aSrc.Length());
}
else
{
TInt len = iRemainData.Length() + aSrc.Length();
if ( !iSrcBuf )
{
TInt maxLen = iRemainData.MaxLength() + 2 * aSrc.Length();
iSrcBuf = HBufC8::NewL(maxLen);
LOG_FORMAT(( _L("in CAacCodec::DecodeAudio, iSrcBuf.MaxLength() = %d"), iSrcBuf->Des().MaxLength() ));
}
else
if ( len > iSrcBuf->Des().MaxLength() )
{
TInt maxLen = 2 * iSrcBuf->Des().MaxLength();
maxLen = Max(maxLen, 2 * len);
delete iSrcBuf;
iSrcBuf = NULL;
iSrcBuf = HBufC8::NewL(maxLen);
LOG_FORMAT(( _L("in CAacCodec::DecodeAudio, iSrcBuf.MaxLength() = %d"), iSrcBuf->Des().MaxLength() ));
}
iSrcBuf->Des().Copy(iRemainData);
iSrcBuf->Des().Append(aSrc);
pSrc.Set((TUint8*)iSrcBuf->Ptr(), iSrcBuf->Length(), iSrcBuf->Des().MaxLength());
}
TInt frameNum = 0;
TInt len = pSrc.Length();
TInt lastFramePos = 0;
const TUint8* datap = pSrc.Ptr();
TInt i = 0;
while ( i < (len - 6) )
{
if ( (datap[i] != 0xff) || ((datap[i+1] & 0xf0) != 0xf0) )
{
if ( (datap[i+2] & 0xf0) != 0xf0 )
{
//LOG_FORMAT((_L("datap[%d] = 0x%02x, datap[%d] = 0x%02x, datap[%d] = 0x%02x"), i, datap[i], i+1, datap[i+1], i+2, datap[i+2]));
}
i++;
continue;
}
TInt frameSize = (datap[i + 2] << 24) | (datap[i + 3] << 16) | (datap[i + 4] << 8) | datap[i + 5];
frameSize &= 0x0003ffc0;
frameSize >>= 5;
if ( frameSize + i >= len )
{ //不完整的帧
break;
}
frameNum++;
lastFramePos = i;
i += frameSize;
}
TInt remainLen = len - lastFramePos;
if ( remainLen > 0 )
{
TInt l = Min(iRemainData.MaxLength(), remainLen);
iRemainData.Copy(pSrc.Right(l));
}
if ( frameNum < 1 )
{ //如果1个帧都没有, 那么无需转换
LOG(_L("========== panic frameNum = 0 ============="));
return EFalse;
}
pSrc.SetLength(lastFramePos);
iSrc->SetPtr(pSrc);
aDest.Zero();
TPtr8 pDest((TUint8*)aDest.Ptr(), 0, aDest.MaxLength());
iDest->SetPtr(pDest);
TCodecProcessResult ret;
TRAPD(perr, ret = iCodec->ProcessL(*iSrc, *iDest));
if ( perr != KErrNone )
{
LOG_FORMAT((_L("iCodec->ProcessL leave = %d"), perr));
return EFalse;
}
else
if ( ret != TCodecProcessResult::EProcessComplete)
{
TBuf<300> phone;
if ( ret == TCodecProcessResult::EProcessIncomplete) phone.Append(_L("EProcessIncomplete"));
if ( ret == TCodecProcessResult::EEndOfData) phone.Append(_L("EEndOfData"));
if ( ret == TCodecProcessResult::EDstNotFilled) phone.Append(_L("EDstNotFilled"));
if ( ret == TCodecProcessResult::EProcessError) phone.Append(_L("EProcessError"));
if ( ret == TCodecProcessResult::EProcessIncompleteRepositionRequest) phone.Append(_L("EProcessIncompleteRepositionRequest"));
if ( ret == TCodecProcessResult::EProcessCompleteRepositionRequest) phone.Append(_L("EProcessCompleteRepositionRequest"));
LOG_FORMAT((_L("iCodec->ProcessL = %S"), &phone));
LOG_FORMAT(( _L("iDest->Data().Length() = %d"), iDest->Data().Length() ));
return EFalse;
}
aDest.SetLength(iDest->Data().Length());
return ETrue;
}