videoeditorengine/audioeditorengine/codecs/MP4/src/ProcMP4InFileHandler.cpp
changeset 0 951a5db380a0
--- /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, 
+        &timescale, 
+        &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, &timescale, &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, 
+            &timestamp, 
+            &returnedframes, 
+            &timestamp2);
+
+        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, 
+        &timescale, 
+        &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;
+        
+    }
+