--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/videoeditorengine/audioeditorengine/codecs/MP4/src/ProcMP4InFileHandler.cpp Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,1365 @@
+/*
+* Copyright (c) 2010 Ixonos Plc.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - Initial contribution
+*
+* Contributors:
+* Ixonos Plc
+*
+* Description:
+*
+*/
+
+
+
+#include <e32base.h>
+#include <f32file.h>
+#include "AudCommon.h"
+#include "ProcConstants.h"
+#include "AWBConstants.h"
+#include "ProcMP4InFileHandler.h"
+#include "mp4aud.h"
+#include "ProcAACFrameHandler.h"
+#include "ProcAMRFrameHandler.h"
+#include "ProcAWBFrameHandler.h"
+#include "audconstants.h"
+
+
+
+#include "ProcTools.h"
+//#include "aacenc_interface.h"
+
+// Debug print macro
+#if defined _DEBUG
+#include <e32svr.h>
+#define PRINT(x) RDebug::Print x;
+#else
+#define PRINT(x)
+#endif
+
+// Max coded AAC frame size (768 bytes per channel)
+const TUint KMaxAACFrameSize(1536);
+
+
+CProcMP4InFileHandler* CProcMP4InFileHandler::NewL(const TDesC& aFileName,
+ RFile* aFileHandle,
+ CAudClip* aClip, TInt aReadBufferSize,
+ TInt aTargetSampleRate,
+ TChannelMode aChannelMode)
+ {
+
+ CProcMP4InFileHandler* self = NewLC(aFileName, aFileHandle, aClip, aReadBufferSize,
+ aTargetSampleRate, aChannelMode);
+ CleanupStack::Pop(self);
+ return self;
+
+ }
+
+CProcMP4InFileHandler* CProcMP4InFileHandler::NewLC(const TDesC& aFileName,
+ RFile* aFileHandle,
+ CAudClip* aClip, TInt aReadBufferSize,
+ TInt aTargetSampleRate,
+ TChannelMode aChannelMode)
+
+ {
+
+ CProcMP4InFileHandler* self = new (ELeave) CProcMP4InFileHandler();
+ CleanupStack::PushL(self);
+ self->ConstructL(aFileName, aFileHandle, aClip, aReadBufferSize,
+ aTargetSampleRate, aChannelMode);
+ return self;
+
+ }
+
+void CProcMP4InFileHandler::GetPropertiesL(TAudFileProperties* aProperties)
+ {
+ PRINT((_L("CProcMP4InFileHandler::GetPropertiesL in") ));
+ if (iProperties != 0)
+ {
+ *aProperties = *iProperties;
+ PRINT((_L("CProcMP4InFileHandler::GetPropertiesL use cached properties, out") ));
+ return;
+ }
+
+ if (iProperties == 0)
+ {
+ iProperties = new (ELeave) TAudFileProperties;
+ }
+
+ mp4_u32 audiolength = 0;
+ mp4_u32 audiotype = 0;
+ mp4_u8 framespersample = 0;
+ mp4_u32 timescale = 0;
+ mp4_u32 averagebitrate = 0;
+
+ aProperties->iFileFormat = EAudFormatUnrecognized;
+ aProperties->iAudioType = EAudTypeUnrecognized;
+ aProperties->iDuration = 0;
+ aProperties->iSamplingRate = 0;
+ aProperties->iBitrate = 0;
+ aProperties->iChannelMode = EAudChannelModeNotRecognized;
+ aProperties->iBitrateMode = EAudBitrateModeNotRecognized;
+ aProperties->iAudioTypeExtension = EAudExtensionTypeNoExtension;
+ aProperties->iFrameLen = 0;
+ aProperties->iFrameDuration = 0;
+ aProperties->iFrameCount = 0;
+ aProperties->iNumFramesPerSample = 1;
+ aProperties->iAACObjectType = EAudAACObjectTypeNone;
+
+ MP4Err err = MP4ParseRequestAudioDescription(iParser,
+ &audiolength,
+ &audiotype,
+ &framespersample,
+ ×cale,
+ &averagebitrate);
+
+
+ if (err == MP4_OK)
+ {
+ if (audiotype == MP4_TYPE_MPEG4_AUDIO)
+ {
+
+ aProperties->iAudioType = EAudAAC_MPEG4;
+ aProperties->iBitrateMode = EAudVariable;
+
+ }
+ else if (audiotype == MP4_TYPE_AMR_NB)
+ {
+ aProperties->iAudioType = EAudAMR;
+ aProperties->iBitrateMode = EAudVariable;
+
+ }
+ else if (audiotype == MP4_TYPE_AMR_WB)
+ {
+ aProperties->iAudioType = EAudAMRWB;
+ aProperties->iBitrateMode = EAudVariable;
+
+ }
+ aProperties->iBitrate = averagebitrate;
+
+ // casting for PC-Lint
+ TInt64 ti = (TInt64)(TInt)(audiolength*1000);
+ TTimeIntervalMicroSeconds TTaudiolength(ti);
+
+ aProperties->iDuration = TTaudiolength;
+ aProperties->iFileFormat = EAudFormatMP4;
+ //aProperties->iFrameLen = framespersample;
+
+
+ }
+ else if (err == MP4_NO_AUDIO)
+ {
+ aProperties->iAudioType = EAudNoAudio;
+ *iProperties = *aProperties;
+ return;
+
+ //User::Leave(KErrGeneral);
+ }
+ else
+ {
+ // a special case: there may be audio track but it is empty; if type was recognized, mark as no audio
+ if ( (audiotype == MP4_TYPE_MPEG4_AUDIO) || (audiotype == MP4_TYPE_AMR_NB) || (audiotype == MP4_TYPE_AMR_WB))
+ {
+ PRINT((_L("CProcMP4InFileHandler::GetPropertiesL problems with getting audio description, mark no audio since audio type was recognized")));
+ aProperties->iAudioType = EAudNoAudio;
+ *iProperties = *aProperties;
+ }
+ PRINT((_L("CProcMP4InFileHandler::GetPropertiesL out with MP4Err %d"), err ));
+ return;
+
+ }
+
+ const TInt KMaxBufferSize = 128;
+
+ mp4_u8 *buffer = new (ELeave) mp4_u8[KMaxBufferSize];
+ CleanupStack::PushL(buffer);
+
+ mp4_u32 decspecinfosize = 0;
+
+ err = MP4ParseReadAudioDecoderSpecificInfo(
+ iParser,
+ buffer,
+ KMaxBufferSize,
+ &decspecinfosize);
+
+
+ mp4AACTransportHandle mp4AAC_ff;
+
+ if (err == MP4_OK && aProperties->iAudioType == EAudAAC_MPEG4)
+ {
+
+ PRINT((_L("CProcMP4InFileHandler::GetPropertiesL AAC found") ));
+
+ TInt ret = ReadMP4AudioConfig(buffer,
+ decspecinfosize,
+ &mp4AAC_ff);
+ if (ret != TRUE)
+ {
+ aProperties->iFileFormat = EAudFormatUnrecognized;
+ aProperties->iAudioType = EAudTypeUnrecognized;
+ User::Leave(KErrNotSupported);
+ }
+
+ // ProgConfig progCfg = mp4AAC_ff.progCfg;
+ AudioSpecificInfo audioInfo = mp4AAC_ff.audioInfo;
+ aProperties->iSamplingRate = audioInfo.samplingFrequency;
+ // TInt tmp = mp4AAC_ff.progCfg.coupling.num_ele;
+
+ // Check that the sample rate is supported
+ if( (aProperties->iSamplingRate != KAedSampleRate8kHz) &&
+ (aProperties->iSamplingRate != KAedSampleRate11kHz) &&
+ (aProperties->iSamplingRate != KAedSampleRate16kHz) &&
+ (aProperties->iSamplingRate != KAedSampleRate22kHz) &&
+ (aProperties->iSamplingRate != KAedSampleRate24kHz) &&
+ (aProperties->iSamplingRate != KAedSampleRate32kHz) &&
+ (aProperties->iSamplingRate != KAedSampleRate44kHz) &&
+ (aProperties->iSamplingRate != KAedSampleRate48kHz) )
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ if (audioInfo.channelConfiguration == 2)
+ {
+ aProperties->iChannelMode = EAudStereo;
+ }
+ else if (audioInfo.channelConfiguration == 1)
+ {
+
+ aProperties->iChannelMode = EAudSingleChannel;
+ }
+ else
+ {
+ aProperties->iChannelMode = EAudChannelModeNotRecognized;
+ }
+
+ if (mp4AAC_ff.audioInfo.samplingFreqIdx !=
+ mp4AAC_ff.progCfg.sample_rate_idx)
+ {
+ aProperties->iFileFormat = EAudFormatUnrecognized;
+ aProperties->iAudioType = EAudTypeUnrecognized;
+ aProperties->iDuration = 0;
+ aProperties->iSamplingRate = 0;
+ aProperties->iBitrate = 0;
+ aProperties->iChannelMode = EAudChannelModeNotRecognized;
+ aProperties->iBitrateMode = EAudBitrateModeNotRecognized;
+ aProperties->iFrameLen = 0;
+ aProperties->iFrameDuration = 0;
+ aProperties->iFrameCount = 0;
+ aProperties->iNumFramesPerSample = 1;
+ CleanupStack::PopAndDestroy(buffer);
+ PRINT((_L("CProcMP4InFileHandler::GetPropertiesL audio not recognized, out") ));
+ User::Leave(KErrNotSupported);
+ return;
+ }
+
+
+
+ iFrameInfo->iSampleRateID = static_cast<TUint8>(mp4AAC_ff.progCfg.sample_rate_idx);
+ iFrameInfo->iSampleRateID = static_cast<TUint8>(mp4AAC_ff.audioInfo.samplingFreqIdx);
+
+
+ iFrameInfo->iProfileID = static_cast<TUint8>(mp4AAC_ff.progCfg.profile);
+
+ aProperties->iAACObjectType = TAudAACObjectType(iFrameInfo->iProfileID);
+
+ if (aProperties->iChannelMode == EAudStereo)
+ {
+ iFrameInfo->iNumChannels = 2;
+ }
+ else if (aProperties->iChannelMode == EAudSingleChannel)
+ {
+ iFrameInfo->iNumChannels = 1;
+ }
+ else
+ {
+ iFrameInfo->iNumChannels = 0;
+ }
+
+
+ iFrameInfo->iIs960 = mp4AAC_ff.audioInfo.gaInfo.FrameLengthFlag;
+
+ iFrameInfo->iNumCouplingChannels = 0;
+
+ iFrameInfo->isSBR = 0;
+ iFrameInfo->iIsParametricStereo = 0;
+
+ /*
+ * Get frame parameters for eAAC+ codec. It is possible that the bitstream
+ * is plain AAC but we don't know it before the 1st frame is parsed!
+ */
+
+ HBufC8* frame = 0;
+ TInt size = 0;
+
+ TInt32 time = 0;
+
+ // Set the iProperties as GetEncAudioFrameL is using it!!
+ *iProperties = *aProperties;
+ if(GetEncAudioFrameL(frame, size, time))
+ {
+ PRINT((_L("CProcMP4InFileHandler::GetPropertiesL check AAC+ parameters") ));
+
+ TUint8* buf = const_cast<TUint8*>(frame->Right(frame->Size()).Ptr());
+ CProcAACFrameHandler::GetEnhancedAACPlusParametersL(buf, frame->Size(), aProperties, iFrameInfo);
+ delete frame;
+ frame = 0;
+ }
+
+ }
+ else if (err == MP4_OK && aProperties->iAudioType == EAudAMR)
+ {
+ aProperties->iChannelMode = EAudSingleChannel;
+ aProperties->iSamplingRate = 8000;
+
+ }
+ else if (err == MP4_OK && aProperties->iAudioType == EAudAMRWB)
+ {
+ aProperties->iChannelMode = EAudSingleChannel;
+ aProperties->iSamplingRate = 16000;
+
+ }
+
+ TInt frameAmount = 0;
+ TInt frameSize = 0;
+ TInt frameDuration = 0;
+
+
+ TInt rv = ETrue;
+
+ *iProperties = *aProperties;
+ rv = GetAudioFrameInfoL(frameAmount, frameDuration, frameSize, aProperties);
+
+ if (rv)
+ {
+ aProperties->iFrameCount = frameAmount;
+ aProperties->iFrameLen = frameSize;
+
+ // casting for PC-Lint
+ TInt64 durMicro = (TInt64) (TInt) frameDuration*1000;
+ aProperties->iFrameDuration = durMicro;
+
+ }
+
+
+
+
+
+ *iProperties = *aProperties;
+
+
+ CleanupStack::PopAndDestroy(buffer);
+
+ PRINT((_L("CProcMP4InFileHandler::GetPropertiesL out") ));
+ }
+
+
+TBool CProcMP4InFileHandler::SeekAudioFrame(TInt32 aTime)
+ {
+
+ mp4_u32 position = static_cast<TUint32>(aTime);
+ mp4_u32 audioPosition = 0;
+
+ mp4_u32 videoPosition = 0;
+ mp4_bool keyframe = EFalse;
+
+ if (iMP4ReadBuffer != 0)
+ {
+ delete[] iMP4ReadBuffer;
+ iMP4ReadBuffer = 0;
+ iMP4ReadBufferPos = 0;
+ iMP4ReadBufferSize = 0;
+ }
+
+ MP4Err err = MP4ParseSeek(iParser,
+ position,
+ &audioPosition,
+ &videoPosition,
+ keyframe);
+
+ if (err == MP4_OK)
+ {
+
+ iCurrentTimeMilliseconds = audioPosition;
+ iLastTimeStamp = audioPosition - I64INT(iProperties->iFrameDuration.Int64()/1000);
+ aTime = audioPosition;
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+TBool CProcMP4InFileHandler::SeekCutInFrame()
+ {
+
+ iCurrentTimeMilliseconds = iCutInTime;
+ return SeekAudioFrame(iCutInTime);
+ }
+
+
+
+TBool CProcMP4InFileHandler::SetNormalizingGainL(const CProcFrameHandler* aFrameHandler)
+{
+
+
+ if (iProperties->iAudioType == EAudAAC_MPEG4)
+ {
+
+ HBufC8* point = 0;
+ TInt siz;
+ TInt32 tim = 0;
+ TInt maxGain = 0;
+ RArray<TInt> gains;
+ TInt maxAverage = 0;
+ TInt tmpGain = 0;
+ TInt gainCounter = 0;
+ TInt timeNow = 0;
+ while(GetEncAudioFrameL(point, siz, tim))
+ {
+
+ aFrameHandler->GetGainL(point, gains, maxGain);
+ timeNow += tim;
+
+ for (TInt a = 0 ; a < gains.Count() ; a++)
+ {
+ tmpGain += gains[a];
+ gainCounter++;
+ }
+ gains.Reset();
+
+ if (timeNow > 1000)
+ {
+ if (tmpGain/gainCounter > maxAverage)
+ {
+ maxAverage = tmpGain/gainCounter;
+ }
+
+ timeNow = 0;
+ tmpGain = 0;
+ gainCounter = 0;
+ }
+
+ delete point;
+
+ }
+
+ // bigger value makes normalizing more efficient, but makes
+ // dynamic compression more likely to occur
+ TInt NormalizingFactor = 175;
+ if (iProperties->iBitrate > 20000 && iProperties->iBitrate < 40000)
+ {
+
+ // 32 kBit/s
+ NormalizingFactor = 170;
+
+ }
+ else if (iProperties->iBitrate > 80000 && iProperties->iBitrate < 110000)
+ {
+ // 96 kBit/s
+ NormalizingFactor = 170;
+
+ }
+
+
+ else if (iProperties->iBitrate > 110000 && iProperties->iBitrate < 140000)
+ {
+ // 128 kBit/s
+ if (iProperties->iChannelMode == EAudSingleChannel)
+ NormalizingFactor = 160;
+ else
+ NormalizingFactor = 170;
+
+ }
+ else if (iProperties->iBitrate > 150000)
+ {
+ // 256 kBit/s
+ if (iProperties->iChannelMode == EAudSingleChannel)
+ NormalizingFactor = 150;
+ else
+ NormalizingFactor = 165;
+
+ }
+ else
+ {
+
+ if (iProperties->iChannelMode == EAudSingleChannel)
+ NormalizingFactor = 170;
+
+ }
+
+
+ TInt gainBoost = (NormalizingFactor-maxAverage)*3;
+
+ if (gainBoost < 0) gainBoost = 0;
+
+ iNormalizingMargin = static_cast<TInt8>(gainBoost);
+
+
+ }
+
+ else if (iProperties->iAudioType == EAudAMR)
+ {
+ HBufC8* point = 0;
+ TInt siz;
+ TInt32 tim = 0;
+ TInt8 margin = 0;
+ TInt minMargin = KMaxTInt;
+ TInt tmpGain = 0;
+ TInt frameCounter = 0;
+ while(GetEncAudioFrameL(point, siz, tim))
+
+ {
+ aFrameHandler->GetNormalizingMargin(point, margin);
+ tmpGain += margin;
+
+ delete point;
+ point = 0;
+ frameCounter++;
+ if (frameCounter > 1)
+ {
+ tmpGain = tmpGain/3;
+
+ if (tmpGain < minMargin)
+ {
+ minMargin = tmpGain;
+ }
+
+ frameCounter = 0;
+ tmpGain = 0;
+ }
+ }
+
+ iNormalizingMargin = static_cast<TInt8>(minMargin);
+ }
+ return ETrue;
+
+}
+
+TBool CProcMP4InFileHandler::ReadAudioDecoderSpecificInfoL(HBufC8*& aBytes, TInt aBufferSize)
+ {
+
+
+ aBytes = HBufC8::NewL(aBufferSize);
+
+ CleanupStack::PushL(aBytes);
+
+ mp4_u8 *buffer = new (ELeave) mp4_u8[aBufferSize];
+ mp4_u32 decspecinfosize = 0;
+
+ MP4Err err = MP4ParseReadAudioDecoderSpecificInfo(
+ iParser,
+ buffer,
+ aBufferSize,
+ &decspecinfosize);
+
+ if (err == MP4_OK)
+ {
+
+ for (TUint a = 0 ; a < decspecinfosize ; a++)
+ {
+ aBytes->Des().Append(buffer[a]);
+ }
+ }
+ else
+ {
+ delete[] buffer;
+ buffer = 0;
+ CleanupStack::PopAndDestroy(aBytes);
+ aBytes = 0;
+ return EFalse;;
+ }
+
+ delete[] buffer;
+ buffer = 0;
+
+ CleanupStack::Pop(aBytes);
+ return ETrue;
+
+
+ }
+
+
+CProcMP4InFileHandler::~CProcMP4InFileHandler()
+ {
+ if (iFileOpen)
+ {
+ MP4ParseClose(iParser);
+ }
+ if (iSilentFrame != 0)
+ {
+ delete iSilentFrame;
+ }
+
+ if (iFrameInfo != 0)
+ {
+ delete iFrameInfo;
+ iFrameInfo = 0;
+ }
+
+ if (iMP4ReadBuffer != 0)
+ {
+ delete[] iMP4ReadBuffer;
+ }
+
+ delete iDecoder;
+
+ delete iFrameHandler;
+
+ }
+
+
+void CProcMP4InFileHandler::ConstructL(const TDesC& aFileName,
+ RFile* aFileHandle,
+ CAudClip* aClip,
+ TInt /*aReadBufferSize*/,
+ TInt aTargetSampleRate,
+ TChannelMode aChannelMode)
+ {
+ //InitAndOpenFileL(aFileName, aCutInTime, aReadBufferSize);
+
+ iFrameInfo = new (ELeave) TAACFrameHandlerInfo;
+
+
+ // init a raw silent frame
+ // in other in file handlers it is created in CProcInFileHandler
+
+ const TInt KBitsPerSample = 16;
+
+ TInt samplesIn20ms = ((iTargetSampleRate) *
+ (KBitsPerSample)/8)/50;
+
+ if (iChannelMode == EAudStereo)
+ {
+ samplesIn20ms *= 2;
+
+ }
+ if (samplesIn20ms % 2 != 0) samplesIn20ms--;
+
+ iRawSilentFrame = HBufC8::NewL(samplesIn20ms);
+
+ iRawSilentFrame->Des().SetLength(samplesIn20ms);
+ iRawSilentFrame->Des().Fill(0);
+
+ iRawSilentFrameDuration = 20;
+
+
+ iClip = aClip;
+
+ iTargetSampleRate = aTargetSampleRate;
+ iChannelMode = aChannelMode;
+
+ if (iParser == 0)
+ {
+
+ MP4Err err;
+ if (aFileHandle)
+ {
+ err = MP4ParseOpenFileHandle(&iParser, aFileHandle);
+ }
+ else
+ {
+ TBuf<258> temp(aFileName);
+ temp.ZeroTerminate();
+ MP4FileName name = (MP4FileName)(temp.Ptr());
+ err = MP4ParseOpen(&iParser , name);
+ }
+
+ if (err == MP4_FILE_ERROR)
+ {
+ User::Leave(KErrNotFound);
+ }
+ else if (err != MP4_OK)
+ {
+ User::Leave(KErrGeneral);
+ }
+ iFileOpen = ETrue;
+
+ }
+
+ TAudFileProperties prop;
+ GetPropertiesL(&prop);
+
+ if (prop.iAudioType == EAudAAC_MPEG4)
+ {
+ // generate a silent frame ------------------>
+
+ if (iProperties->iChannelMode == EAudSingleChannel)
+ {
+
+ iSilentFrame = HBufC8::NewL(KSilentMonoAACFrameLenght);
+ iSilentFrame->Des().Append(KSilentMonoAACFrame, KSilentMonoAACFrameLenght);
+
+ }
+ else if (iProperties->iChannelMode == EAudStereo)
+ {
+
+ iSilentFrame = HBufC8::NewL(KSilentStereoAACFrameLenght);
+ iSilentFrame->Des().Append(KSilentStereoAACFrame, KSilentStereoAACFrameLenght);
+
+
+ }
+ else
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+
+ mp4_u32 frameDurationMilli = ProcTools::MilliSeconds(iProperties->iFrameDuration);
+
+
+ iSilentFrameDuration = frameDurationMilli;
+
+
+
+ // <------------------generate a silent frame
+
+ iFrameHandler = CProcAACFrameHandler::NewL(*iFrameInfo);
+
+ }
+ else if (prop.iAudioType == EAudAMR)
+ {
+ const TInt KSilentFrameSize = 13;
+
+ TUint8 silentFrame[KSilentFrameSize]=
+ {
+ 0x04,0x63,0x3C,0xC7,0xF0,0x03,0x04,0x39,0xFF,0xE0,
+ 0x00,0x00,0x00
+ };
+
+
+ iSilentFrame = HBufC8::NewL(KSilentFrameSize);
+ iSilentFrame->Des().Append(silentFrame, KSilentFrameSize);
+ iSilentFrameDuration = 20;
+
+
+ iFrameHandler = CProcAMRFrameHandler::NewL();
+
+ }
+ else if (prop.iAudioType == EAudAMRWB)
+ {
+ TUint8 sf[18] = {0x04,0x10,0x20,0x00,0x21,
+ 0x1C,0x14,0xD0,0x11,0x40,0x4C,0xC1,0xA0,
+ 0x50,0x00,0x00,0x44,0x30};
+ iSilentFrame = HBufC8::NewL(18);
+ iSilentFrame->Des().Append(sf,18);
+ iSilentFrameDuration = 20;
+
+ iFrameHandler = CProcAWBFrameHandler::NewL();
+
+ }
+ else if (prop.iAudioType == EAudNoAudio )
+ {
+ iDecodingPossible = EFalse;
+ return;
+ }
+
+ if (aClip != 0)
+ {
+ iCutInTime = ProcTools::MilliSeconds(aClip->CutInTime());
+
+ }
+
+ iDecoder = CProcDecoder::NewL();
+
+ iDecodingPossible = iDecoder->InitL(*iProperties, aTargetSampleRate, aChannelMode);
+
+ if (iClip != 0 && iClip->Normalizing())
+ {
+ SetNormalizingGainL(iFrameHandler);
+ }
+
+
+ }
+
+CProcMP4InFileHandler::CProcMP4InFileHandler() : CProcInFileHandler(), iParser(0),
+ iLastTimeStamp(0), iFrameInfo(0)
+ {
+
+ }
+
+TBool CProcMP4InFileHandler::GetAudioFrameInfoL(TInt& aFrameAmount,
+ TInt& aAverageFrameDuration,
+ TInt& aAverageFrameSize,
+ TAudFileProperties* aProperties)
+ {
+
+ PRINT((_L("CProcMP4InFileHandler::GetAudioFrameInfoL in")));
+ mp4_u32 audiolength = 0;
+ mp4_u32 audiotype = 0;
+
+ mp4_u8 framespersample = 0;
+ mp4_u32 timescale = 0;
+ mp4_u32 averagebitrate = 0;
+
+ if (aProperties->iSamplingRate == 0) return KErrNotSupported;
+
+ MP4Err err = MP4ParseRequestAudioDescription(iParser, &audiolength, &audiotype,
+ &framespersample, ×cale, &averagebitrate);
+
+
+ if (aProperties->iAudioType == EAudAMR)
+ {
+ aAverageFrameDuration = 20;
+
+ }
+ else if(aProperties->iAudioType == EAudAMRWB)
+ {
+ aAverageFrameDuration = 20;
+
+ }
+ else if(aProperties->iAudioType == EAudAAC_MPEG4)
+ {
+
+ aAverageFrameDuration = (1024*1000)/(aProperties->iSamplingRate);
+
+ }
+ else
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ aFrameAmount = TInt((TInt)audiolength/aAverageFrameDuration);
+
+ mp4_u32 lastPosition = 0;
+
+ err = MP4ParseGetLastPosition(iParser, &lastPosition);
+
+ SeekAudioFrame(0);
+
+
+ if (err != MP4_OK)
+ {
+ return EFalse;
+
+ }
+
+ // ignore the first 2 frames
+ HBufC8* frame;
+ TInt size = 0;
+ TInt32 time = 0;
+
+
+ if(GetEncAudioFrameL(frame, size, time))
+ {
+
+ if (aProperties->iAudioType == EAudAAC_MPEG4)
+ {
+
+ /*
+ * Read the eAAC+ parameters. Please note that the decoder specific
+ * configuration information does, in case of explicit signalling,
+ * signal the presence of SBR bitstream elements but not completely
+ * the configuration of the SBR. For example, parametric stereo is
+ * signalled only at the bitstream level (due to backwards comptibility
+ * reasons).
+ */
+
+ TUint8* buf = const_cast<TUint8*>(frame->Right(frame->Size()).Ptr());
+ CProcAACFrameHandler::GetEnhancedAACPlusParametersL(buf, size, aProperties, iFrameInfo);
+
+ }
+ delete frame;
+ frame = 0;
+ }
+
+ if (GetEncAudioFrameL(frame, size, time))
+ {
+ delete frame;
+ frame = 0;
+ }
+
+ // calculate the average of the next 100 frames
+
+ TInt32 timeSum = 0;
+ TInt32 sizeSum = 0;
+ TInt divider = 0;
+ TInt maxFrameNr = 100;
+ if ( aFrameAmount < 100 )
+ {
+ maxFrameNr = aFrameAmount;
+ }
+
+
+ for (TInt a = 0 ; a < maxFrameNr ; a++)
+ {
+ if (GetEncAudioFrameL(frame, size, time))
+ {
+ timeSum += time;
+ sizeSum += size;
+ divider++;
+ delete frame;
+ frame = 0;
+ }
+ else
+ {
+
+ if ( a > 0 )
+ {
+ PRINT((_L("CProcMP4InFileHandler::GetAudioFrameInfoL breaking the loop since less than 100 frames in input (%d)"),a));
+ break;
+ }
+ else
+ {
+ PRINT((_L("CProcMP4InFileHandler::GetAudioFrameInfoL can't get any frames from input")));
+ SeekAudioFrame(lastPosition);
+ return EFalse;
+ }
+ }
+
+ }
+
+ if (divider > 0)
+ {
+ aAverageFrameDuration = static_cast<TInt>(timeSum/divider);
+ aAverageFrameSize = static_cast<TInt>(sizeSum/divider);
+ }
+
+ SeekAudioFrame(lastPosition);
+
+ PRINT((_L("CProcMP4InFileHandler::GetAudioFrameInfoL out")));
+ return ETrue;
+ }
+
+
+TBool CProcMP4InFileHandler::GetEncAudioFrameL(HBufC8*& aFrame, TInt& aSize, TInt32& aTime)
+ {
+ PRINT((_L("CProcMP4InFileHandler::GetEncAudioFrameL in")));
+ if (iParser == 0)
+ {
+ aFrame = 0;
+ return EFalse;
+ }
+
+ mp4_u32 type = 0;
+ if (iProperties->iAudioType == EAudAAC_MPEG4)
+ type = MP4_TYPE_MPEG4_AUDIO;
+ else if (iProperties->iAudioType == EAudAMR)
+ {
+ type = MP4_TYPE_AMR_NB;
+ if (iMP4ReadBuffer != 0 && iMP4ReadBufferSize > 0 && iMP4ReadBufferPos < iMP4ReadBufferSize)
+ {
+ // we can just read a frame from in-buffer
+ aTime = 20;
+ TBool ret = ReadOneAMRFrameL(aFrame);
+
+ if (iClip != 0 && iFrameHandler != 0)
+ {
+ TRAPD(err0, ManipulateGainL(aFrame));
+ if (err0 != KErrNone)
+ {
+ // something went wrong with the gain manipulation
+ // continue by returning the original frame
+ }
+
+ }
+ PRINT((_L("CProcMP4InFileHandler::GetEncAudioFrameL out from AMRNB branch")));
+ return ret;
+ }
+ else
+ {
+ // if nothing more to read in the inBuffer
+ delete[] iMP4ReadBuffer;
+ iMP4ReadBuffer = 0;
+ iMP4ReadBufferPos = 0;
+ iMP4ReadBufferSize = 0;
+ }
+
+
+ // see if stuff left in the read buffer
+ }
+
+ else if (iProperties->iAudioType == EAudAMRWB)
+ {
+ type = MP4_TYPE_AMR_WB;
+
+ if (iMP4ReadBuffer != 0 && iMP4ReadBufferSize > 0 && iMP4ReadBufferPos < iMP4ReadBufferSize)
+ {
+ // we can just read a frame from in-buffer
+ aTime = 20;
+ TBool ret = ReadOneAWBFrameL(aFrame);
+
+ if (iClip != 0 && iFrameHandler != 0)
+ {
+ TRAPD(err0, ManipulateGainL(aFrame));
+ if (err0 != KErrNone)
+ {
+ // something went wrong with the gain manipulation
+ // continue by returning the original frame
+ }
+
+ }
+ PRINT((_L("CProcMP4InFileHandler::GetEncAudioFrameL out from AMRWB branch")));
+ return ret;
+ }
+
+ }
+
+
+
+ mp4_u32 framesize = 0;
+ mp4_u32 audiosize = 0;
+ mp4_u32 timestamp = 0;
+ mp4_u32 returnedframes = 0;
+ mp4_u32 timestamp2 = 0;
+
+ MP4Err err =MP4ParseNextFrameSize(iParser, type, &framesize);
+ if (err == MP4_OK)
+ {
+
+ // some error handling
+ if (type == MP4_TYPE_MPEG4_AUDIO && (framesize > KMaxAACFrameSize))
+ {
+ // we got too many bytes for some reason...
+ delete[] iMP4ReadBuffer;
+ iMP4ReadBuffer = 0;
+ iMP4ReadBufferSize = 0;
+ iMP4ReadBufferPos = 0;
+ PRINT((_L("CProcClipInfoAO::CProcMP4InFileHandler::GetEncAudioFrameL out, too many bytes for AAC %d"), framesize ));
+ return EFalse;
+
+ }
+
+
+ iMP4ReadBufferSize = framesize;
+ delete[] iMP4ReadBuffer;
+ iMP4ReadBuffer = 0;
+ iMP4ReadBuffer = new (ELeave) mp4_u8[framesize];
+ iMP4ReadBufferPos = 0;
+
+ err = MP4ParseReadAudioFrames(iParser,
+ iMP4ReadBuffer,
+ framesize,
+ &audiosize,
+ ×tamp,
+ &returnedframes,
+ ×tamp2);
+
+ if (err == MP4_OK)
+ {
+ aSize = framesize;
+ aTime = timestamp - iLastTimeStamp;
+ iCurrentTimeMilliseconds = timestamp;
+ iLastTimeStamp = timestamp;
+
+ if (type == MP4_TYPE_MPEG4_AUDIO)
+ {
+ aFrame = HBufC8::NewL(audiosize);
+ aFrame->Des().Append(iMP4ReadBuffer, audiosize);
+
+ }
+ else if (type == MP4_TYPE_AMR_NB)
+ {
+ aTime = 20;
+ ReadOneAMRFrameL(aFrame);
+ }
+ else if (type == MP4_TYPE_AMR_WB)
+ {
+ aTime = 20;
+ ReadOneAWBFrameL(aFrame);
+ }
+ }
+ else
+ {
+ delete[] iMP4ReadBuffer;
+ iMP4ReadBuffer = 0;
+ iMP4ReadBufferSize = 0;
+ iMP4ReadBufferPos = 0;
+ PRINT((_L("CProcMP4InFileHandler::GetEncAudioFrameL out since MP4ParseReadAudioFrames failed")));
+ return EFalse;
+
+ }
+
+ // delete if MP4AUDIO.
+ // AMR frames will be read from buffer as MP4 library
+ // might have returned more than one AMR-frames
+ if (type == MP4_TYPE_MPEG4_AUDIO)
+ {
+ delete[] iMP4ReadBuffer;
+ iMP4ReadBuffer = 0;
+ iMP4ReadBufferSize = 0;
+ iMP4ReadBufferPos = 0;
+ }
+
+ }
+ else
+ {
+ PRINT((_L("CProcMP4InFileHandler::GetEncAudioFrameL out since MP4ParseNextFrameSize failed, error %d"),err));
+ return EFalse;
+
+ }
+
+ TInt err2 = KErrNone;
+
+ if (iProperties->iAudioTypeExtension == EAudExtensionTypeNoExtension)
+ {
+
+ // AAC Plus is manipulated in time domain
+
+ if (iClip != 0 && iFrameHandler != 0)
+ {
+ TRAP(err2, ManipulateGainL(aFrame));
+ }
+
+ }
+
+ if (err2 != KErrNone)
+ {
+ // something went wrong with the gain manipulation
+ // continue by returning the original frame
+ }
+ aSize = aFrame->Size();
+
+ PRINT((_L("CProcMP4InFileHandler::GetEncAudioFrameL out successfully")));
+ return ETrue;
+ }
+
+
+TBool CProcMP4InFileHandler::ReadTimeScale(mp4_u32& aTimescale)
+ {
+
+ mp4_u32 audiolength = 0;
+ mp4_u32 audiotype = 0;
+ mp4_u8 framespersample = 0;
+ mp4_u32 timescale = 0;
+ mp4_u32 averagebitrate = 0;
+
+ MP4Err err = MP4ParseRequestAudioDescription(iParser,
+ &audiolength,
+ &audiotype,
+ &framespersample,
+ ×cale,
+ &averagebitrate);
+
+
+
+ if (err == MP4_OK)
+ {
+ aTimescale = timescale;
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+
+ }
+
+
+MP4Err CProcMP4InFileHandler::ParseRequestAudioDescription(
+ mp4_u32 *aAudiolength,
+ mp4_u32 *aAudiotype,
+ mp4_u8 *aFramespersample,
+ mp4_u32 *aTimescale,
+ mp4_u32 *aAveragebitrate)
+
+ {
+
+ return MP4ParseRequestAudioDescription(iParser,
+ aAudiolength,
+ aAudiotype,
+ aFramespersample,
+ aTimescale,
+ aAveragebitrate);
+
+ }
+
+
+TBool CProcMP4InFileHandler::GetInfoForFrameHandler(TAACFrameHandlerInfo& aAACInfo)
+ {
+ if (iParser == 0)
+ {
+ return EFalse;
+ }
+
+ aAACInfo.iIs960 = iFrameInfo->iIs960;
+ aAACInfo.iIsParametricStereo = iFrameInfo->iIsParametricStereo;
+ aAACInfo.iNumChannels = iFrameInfo->iNumChannels;
+ aAACInfo.iNumCouplingChannels = iFrameInfo->iNumCouplingChannels;
+ aAACInfo.iProfileID = iFrameInfo->iProfileID;
+ aAACInfo.iSampleRateID = iFrameInfo->iSampleRateID;
+ aAACInfo.isSBR = iFrameInfo->isSBR;
+
+
+ mp4_u8 *buffer = 0;
+
+ const TInt bufSize = 64;
+ TRAPD(nerr, buffer = new (ELeave) mp4_u8[bufSize])
+
+ if (nerr != KErrNone)
+ {
+ delete[] buffer;
+ return EFalse;
+ }
+
+
+ mp4_u32 decspecinfosize = 0;
+
+ MP4Err err = MP4ParseReadAudioDecoderSpecificInfo(
+ iParser,
+ buffer,
+ 64,
+ &decspecinfosize);
+
+
+ if (err == MP4_OK)
+ {
+
+ mp4AACTransportHandle mp4AAC_ff;
+ int16 err2 = ReadMP4AudioConfig(buffer,
+ decspecinfosize,
+ &mp4AAC_ff);
+ if (err2 != TRUE)
+ {
+
+ delete[] buffer;
+ return EFalse;
+
+ }
+
+ aAACInfo.iSampleRateID = static_cast<TUint8>(mp4AAC_ff.progCfg.sample_rate_idx);
+ aAACInfo.iSampleRateID = static_cast<TUint8>(mp4AAC_ff.audioInfo.samplingFreqIdx);
+
+ aAACInfo.iProfileID = static_cast<TUint8>(mp4AAC_ff.progCfg.profile);
+
+ if (iProperties->iChannelMode == EAudStereo)
+ {
+ aAACInfo.iNumChannels = 2;
+ }
+ else if (iProperties->iChannelMode == EAudSingleChannel)
+ {
+ aAACInfo.iNumChannels = 1;
+ }
+ else
+ {
+ aAACInfo.iNumChannels = 0;
+ }
+
+
+ aAACInfo.iIs960 = mp4AAC_ff.audioInfo.gaInfo.FrameLengthFlag;
+
+ aAACInfo.iNumCouplingChannels = 0;
+
+ aAACInfo.iIsParametricStereo = 0;
+ aAACInfo.isSBR = 0;
+
+ }
+
+ else
+ {
+
+ delete[] buffer;
+ return EFalse;
+
+ }
+
+ delete[] buffer;
+ return ETrue;
+
+
+
+ }
+
+
+
+
+TBool CProcMP4InFileHandler::ReadOneAMRFrameL(HBufC8*& aOneAMRFrame)
+ {
+ if (iMP4ReadBuffer == 0 || iMP4ReadBufferSize < 1
+ || iMP4ReadBufferPos >= iMP4ReadBufferSize)
+ {
+ aOneAMRFrame = 0;
+ return EFalse;
+ }
+
+
+ TInt readSize = 0;
+ TUint8 dec_mode = (enum Mode)((iMP4ReadBuffer[iMP4ReadBufferPos] & 0x0078) >> 3);
+
+ switch (dec_mode)
+ {
+ case 0:
+ readSize = 12;
+ break;
+ case 1:
+ readSize = 13;
+ break;
+ case 2:
+ readSize = 15;
+ break;
+ case 3:
+ readSize = 17;
+ break;
+ case 4:
+ readSize = 19;
+ break;
+ case 5:
+ readSize = 20;
+ break;
+ case 6:
+ readSize = 26;
+ break;
+ case 7:
+ readSize = 31;
+ break;
+ case 8:
+ readSize = 5;
+ break;
+ case 15:
+ readSize = 0;
+ break;
+ default:
+ readSize = 0;
+ break;
+ };
+
+ aOneAMRFrame = HBufC8::NewL(readSize+1);
+
+// TPtr8 tmpDes((TPtr8)aOneAMRFrame->Des());
+
+ TInt lastByte = iMP4ReadBufferPos + readSize;
+
+ for (; iMP4ReadBufferPos <= lastByte ; iMP4ReadBufferPos++)
+ {
+
+ aOneAMRFrame->Des().Append(iMP4ReadBuffer[iMP4ReadBufferPos]);
+ }
+// iMP4ReadBufferPos++;
+
+ return ETrue;
+
+ }
+
+TBool CProcMP4InFileHandler::ReadOneAWBFrameL(HBufC8*& aOneAWBFrame)
+ {
+ if (iMP4ReadBuffer == 0 || iMP4ReadBufferSize < 1
+ || iMP4ReadBufferPos >= iMP4ReadBufferSize)
+ {
+ aOneAWBFrame = 0;
+ return EFalse;
+ }
+ TUint8 toc = iMP4ReadBuffer[iMP4ReadBufferPos];
+ TUint8 mode = static_cast<TUint8>((toc >> 3) & 0x0F);
+
+ TInt readSize = KAWBPacked_size[mode];
+
+ aOneAWBFrame = HBufC8::NewL(readSize+1);
+
+ TInt lastByte = iMP4ReadBufferPos + readSize;
+
+ for (; iMP4ReadBufferPos <= lastByte ; iMP4ReadBufferPos++)
+ {
+
+ aOneAWBFrame->Des().Append(iMP4ReadBuffer[iMP4ReadBufferPos]);
+ }
+
+ return ETrue;
+
+ }
+