--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/audio/ARM_CMMF_codecs/FrameTable/Src/FrameTable.cpp Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,1404 @@
+/*
+
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+
+* All rights reserved.
+
+* This component and the accompanying materials are made available
+
+* under the terms of "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:
+
+*
+
+* Description: Class definition for the frame table functions.
+
+ *
+
+*/
+
+
+
+
+
+// INCLUDES
+
+#include "FrameTable.h"
+
+#include "DebugMacros.h"
+
+#include <e32debug.h>
+
+
+
+// CONSTANTS
+
+const TInt KBuffersToKeep = 3;
+
+const TInt KLowResPeriodMs = 1000; // approximate interval for entries stored in low res table is 1 sec
+
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::CFrameTable
+
+// C++ default constructor can NOT contain any code, that
+
+// might leave.
+
+// -----------------------------------------------------------------------------
+
+//
+
+CFrameTable::CFrameTable()
+
+ {
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::ConstructL
+
+// Symbian 2nd phase constructor can leave.
+
+// -----------------------------------------------------------------------------
+
+//
+
+void CFrameTable::ConstructL()
+
+ {
+
+ DP0(_L("CFrameTable::ConstructL"));
+
+ SetSourceReference(0,0);
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::NewL
+
+// Two-phased constructor.
+
+// -----------------------------------------------------------------------------
+
+//
+
+EXPORT_C CFrameTable* CFrameTable::NewL()
+
+ {
+
+ DP0(_L("CFrameTable::NewL"));
+
+
+
+ CFrameTable* self = new(ELeave) CFrameTable;
+
+ CleanupStack::PushL(self);
+
+ self->ConstructL();
+
+ CleanupStack::Pop(self);
+
+ return self;
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::~CFrameTable
+
+// -----------------------------------------------------------------------------
+
+//
+
+EXPORT_C CFrameTable::~CFrameTable()
+
+ {
+
+ DP0(_L("CFrameTable::~CFrameTable"));
+
+ iFrameTable.Close();
+
+ iLowResFrameTable.Close();
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::InitFrameTable
+
+// -----------------------------------------------------------------------------
+
+//
+
+EXPORT_C TInt CFrameTable::InitFrameTable(TInt aSampleRate, TInt aSamplesPerFrame)
+
+ { // this is only intended to be used at the very beginning of play since it clears the table
+
+ DP2(_L("CFrameTable::InitFrameTable aSampleRate[%d], aSamplesPerFrame[%d]"), aSampleRate, aSamplesPerFrame);
+
+ TInt status = KErrNone;
+
+ ResetTable();
+
+ iSampleRate = aSampleRate;
+
+ iSamplesPerFrame = aSamplesPerFrame;
+
+
+
+ if ((iSampleRate> 0) && (iSamplesPerFrame> 0))
+
+ {
+
+ iMsecPerFrame = (iSamplesPerFrame*1000)/iSampleRate;
+
+ iFramesPerLowResInterval = ((iSampleRate*KLowResPeriodMs/1000) / iSamplesPerFrame);
+
+ iLowResIntervalMs = (iSamplesPerFrame*1000*iFramesPerLowResInterval)/iSampleRate;
+
+ }
+
+ else
+
+ {
+
+ status = KErrArgument;
+
+ }
+
+
+
+ return status;
+
+ }
+
+
+
+// 0 1 2 3 4
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::SubmitTableEntry
+
+// -----------------------------------------------------------------------------
+
+//
+
+// The table will always have contiguous frames in it.
+
+EXPORT_C TInt CFrameTable::SubmitTableEntry(TUint aPos)
+
+ {
+
+ DP2(_L("CFrameTable::SubmitTableEntry aPos[%u], event pos[%u]"), aPos, iPosEventMs);
+
+ TInt status = KErrNone;
+
+ TBufRefPosEntry lastEntry;
+
+ lastEntry.iPos = 0;
+
+ TBufRefPosEntry bufRefPos;
+
+ TUint frameNum;
+
+
+
+ TUint pos = aPos+iOffset; // pos = absolute position (not including any header)
+
+
+
+ if (aPos> 0)
+
+ {
+
+ iCurrentFrameCount++; // not a total frame count, but count from last reference set
+
+ DP1(_L("CFrameTable::SubmitTableEntry iCurrentFrameCount[%u]"), iCurrentFrameCount);
+
+ }
+
+
+
+ TUint numEntries = iFrameTable.Count(); // this table will stay short - seeking backward resets it
+
+
+
+ if (numEntries == 0)
+
+ { // table gets reset if seeking in source
+
+ bufRefPos.iPos = pos;
+
+ bufRefPos.iFrameNum = iFrameNum; // first frame num is 0 so calculations for time 0 would point to frame 0
+
+ status = iFrameTable.Append(bufRefPos);
+
+ ASSERT(status == KErrNone);
+
+ numEntries = 1;
+
+ DP2(_L("CFrameTable::SubmitTableEntry init pos[%u] framenum[%u]"), pos, iFrameNum);
+
+ }
+
+ else
+
+ {
+
+ lastEntry = iFrameTable[numEntries-1];
+
+
+
+ if (pos> lastEntry.iPos)
+
+ {
+
+ frameNum = lastEntry.iFrameNum + 1;
+
+ bufRefPos.iPos = pos;
+
+ bufRefPos.iFrameNum = frameNum;
+
+
+
+ DP3 (_L ("CFrameTable::SubmitTableEntry, new entry iPos[%u], iFrameNum[%u], cnt[%u]"), bufRefPos.iPos, bufRefPos.iFrameNum, numEntries+1);
+
+
+
+ status = iFrameTable.Append(bufRefPos);
+
+ ASSERT(status == KErrNone);
+
+ if (iOkToShrink)
+
+ {
+
+ DP0(_L("CFrameTable::SubmitTableEntry removing an entry "));
+
+ iFrameTable.Remove(0);
+
+ }
+
+ }
+
+ else
+
+ {
+
+ status = KErrArgument;
+
+ }
+
+ }
+
+
+
+ if (status == KErrNone)
+
+ {
+
+ SubmitLowResTableEntry(bufRefPos); // do this before events are detected below
+
+
+
+ // total average bitrate - not instantaneous bitrate - used for duration calculation
+
+ if (pos> iLastBytePos)
+
+ { // don't recalculate if we rewind
+
+ iLastBytePos = pos; // pos is absolute position - relative to the start of actual data content (not file start - no metadata) as set by the user. User maintains metadata offsets.
+
+ TUint totalTimeMs = bufRefPos.iFrameNum*iMsecPerFrame; // total time in the table
+
+ DP1(_L("CFrameTable::SubmitTableEntry totalTimeMs[%u]"), totalTimeMs);
+
+ if (totalTimeMs> 0)
+
+ {
+
+ // cast calculation to TIn64 or it could lose precision
+
+ TUint64 p = pos;
+
+ p = p*8*1000;
+
+ TUint64 t = totalTimeMs;
+
+ iAvgBitrate = p/t;
+
+ }
+
+ }
+
+ }
+
+
+
+ // need to convert current position to time
+
+ TInt currentTimeMs = iCurrentFrameCount*iMsecPerFrame + iTimeRefMs; // current time position being played
+
+ DP3(_L("CFrameTable::SubmitTableEntry current calculated time ms[%u] iCurrentFrameCount[%u] timeref[%u]"), currentTimeMs, iCurrentFrameCount, iTimeRefMs);
+
+ if (iPosEventMs> 0)
+
+ { // used for seeking
+
+ if (currentTimeMs >= iPosEventMs)
+
+ {
+
+ iPosEventMs = 0;
+
+ DP0(_L("CFrameTable::SubmitTableEntry handle event pos reached"));
+
+ iEventPos = pos;
+
+ iObserver->HandleFrameTableEvent(EPosReached);
+
+ }
+
+ }
+
+
+
+ if (iPlayWindowEndPosEventMs> 0)
+
+ {
+
+ if (currentTimeMs >= iPlayWindowEndPosEventMs)
+
+ {
+
+ iPlayWindowEndPosEventMs = 0;
+
+ DP0(_L("CFrameTable::SubmitTableEntry handle event play window end pos reached"));
+
+ iObserver->HandleFrameTableEvent(EPlayWindowEndPosReached);
+
+ }
+
+ }
+
+
+
+ if (iIntervalEvent> 0)
+
+ {
+
+ if (iIntervalRef == 0)
+
+ {
+
+ iIntervalRef = currentTimeMs;
+
+ }
+
+
+
+ if ((currentTimeMs - iIntervalRef) >= iIntervalEvent)
+
+ {
+
+ iIntervalRef = currentTimeMs;
+
+ iObserver->HandleFrameTableEvent(EDecodeInterval);
+
+ }
+
+ }
+
+
+
+ DP1 (_L ("CFrameTable::SubmitTableEntry, avgBitRate[%u]"), iAvgBitrate);
+
+ return status;
+
+ }
+
+
+
+TInt CFrameTable::SubmitLowResTableEntry(TBufRefPosEntry& aEntry)
+
+ {
+
+ TInt status = KErrNone;
+
+ TBufRefPosEntry lastEntry;
+
+
+
+ TUint numEntries = iLowResFrameTable.Count();
+
+ if (numEntries == 0)
+
+ {
+
+ status = iLowResFrameTable.Append(aEntry);
+
+ ASSERT(status == KErrNone);
+
+ return status;
+
+ }
+
+
+
+ lastEntry = iLowResFrameTable[numEntries-1];
+
+
+
+ ASSERT(aEntry.iFrameNum <= lastEntry.iFrameNum + iFramesPerLowResInterval);
+
+ // note that 0 position table entries can be submitted to the table before it is initialized.
+
+ // If this happens, iFramesPerLowResInterval would still be 0 and the same entry might be appended again
+
+ // so we have a check to make sure that doesn't happen.
+
+ if ((aEntry.iFrameNum == lastEntry.iFrameNum + iFramesPerLowResInterval) &&
+
+ (iFramesPerLowResInterval != 0))
+
+ {
+
+ DP3 (_L ("CFrameTable::SubmitLowResTableEntry, new entry aEntry.iFrameNum[%u], lastEntry.iFrameNum[%u], iFramesPerLowResInterval[%u]"), aEntry.iFrameNum, lastEntry.iFrameNum, iFramesPerLowResInterval);
+
+ DP3 (_L ("CFrameTable::SubmitLowResTableEntry, new entry iPos[%u], iFrameNum[%u], cnt[%u]"), aEntry.iPos, aEntry.iFrameNum, numEntries+1);
+
+
+
+ status = iLowResFrameTable.Append(aEntry);
+
+ ASSERT(status == KErrNone);
+
+ }
+
+ else
+
+ {
+
+ status = KErrArgument;
+
+ }
+
+
+
+ return status;
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::FindFramePosFromTime
+
+// -----------------------------------------------------------------------------
+
+//
+
+/*
+
+ Looks in the table for the frame position associated with the given time.
+
+ It will return the position and also the time for that frame.
+
+ If not found, an error will be returned, and the time and position will be
+
+ the closest available in the table.
+
+ */
+
+EXPORT_C TInt CFrameTable::FindFramePosFromTime(TUint& aTimeMs, TUint& aPos)
+
+ {
+
+ DP2(_L("CFrameTable::FindFramePosFromTime time[%u], pos[%u]"), aTimeMs, aPos);
+
+ TInt stat = KErrNone;
+
+ // TUint in msec can represent 1193 hours
+
+ TInt tableIndex;
+
+
+
+ // special case for time = 0
+
+ if (aTimeMs == 0)
+
+ {
+
+ aPos = 0;
+
+ DP0(_L("CFrameTable::FindFramePosFromTime time=0 pos=0"));
+
+ return KErrNone;
+
+ }
+
+
+
+ TUint countlr = iLowResFrameTable.Count();
+
+ if ((countlr == 0) || (iMsecPerFrame == 0))
+
+ {
+
+ DP2(_L("CFrameTable::FindFramePosFromTime not ready countlr[%u] iMsecPerFrame[%u]"), countlr, iMsecPerFrame);
+
+ return KErrNotReady;
+
+ }
+
+ TUint frame = aTimeMs/iMsecPerFrame; // calc frame number
+
+ DP1(_L("CFrameTable::FindFramePosFromTime looking for frame[%u]"), frame);
+
+
+
+ // check hi-res table first
+
+ TUint count = iFrameTable.Count();
+
+ if (count == 0)
+
+ {
+
+ stat = KErrNotFound; // use low-res table
+
+ }
+
+ else
+
+ {
+
+ TUint frame0 = iFrameTable[0].iFrameNum; // first frame available (table can shrink)
+
+ DP1(_L("CFrameTable::FindFramePosFromTime frame0[%u]"), frame0);
+
+ if (frame >= frame0) // frame might be in table
+
+
+
+ {
+
+ tableIndex = frame - frame0; // calc index into table
+
+ DP1(_L("CFrameTable::FindFramePosFromTime tableIndex[%u]"), tableIndex);
+
+ if (tableIndex >= count)
+
+ {
+
+ stat = KErrNotFound; // use low-res table
+
+ DP0(_L("CFrameTable::FindFramePosFromTime not found in hi-res"));
+
+ }
+
+ else
+
+ {
+
+ aPos = iFrameTable[tableIndex].iPos;
+
+ iFrameNum = iFrameTable[tableIndex].iFrameNum; // iFrameNum provides frame num after hi-res table is reset
+
+ aTimeMs = iFrameNum * iMsecPerFrame;
+
+ DP4(_L("CFrameTable::FindFramePosFromTime aTimeMs[%u] iFrameNum[%u] iSamplesPerFrame[%u] iSampleRate[%u]"),
+
+ aTimeMs,iFrameNum,iSamplesPerFrame,iSampleRate);
+
+ }
+
+ }
+
+ else
+
+ {
+
+ stat = KErrNotFound; // use low-res table
+
+ }
+
+ }
+
+ if (stat == KErrNotFound)
+
+ { // check low-res table
+
+ DP0(_L("CFrameTable::FindFramePosFromTime looking in low-res table"));
+
+ if (iFramesPerLowResInterval> 0)
+
+ { // first frame is always 0 in low res table - don't need to subtract frame[0]
+
+ tableIndex = frame/iFramesPerLowResInterval; // calc index into table
+
+ DP3(_L("CFrameTable::FindFramePosFromTime tableIndex[%d] frame[%u] iFramesPerLowResInterval[%u]"),
+
+ tableIndex,frame,iFramesPerLowResInterval);
+
+ if (tableIndex < countlr)
+
+ {
+
+ aPos = iLowResFrameTable[tableIndex].iPos;
+
+ iFrameNum = iLowResFrameTable[tableIndex].iFrameNum; // iFrameNum provides frame num after hi-res table is reset
+
+ aTimeMs = iFrameNum * iMsecPerFrame;
+
+ stat = KErrNone;
+
+ }
+
+ }
+
+ }
+
+
+
+ if (stat == KErrNotFound)
+
+ { // use last in low-res table
+
+ aPos = iLowResFrameTable[countlr-1].iPos;
+
+ iFrameNum = iLowResFrameTable[countlr-1].iFrameNum; // iFrameNum provides frame num after hi-res table is reset
+
+ aTimeMs = iFrameNum * iMsecPerFrame;
+
+ }
+
+ DP4(_L("CFrameTable::FindFramePosFromTime time[%u], pos[%u], stat[%d] iFrameNum sync[%u]"), aTimeMs, aPos, stat, iFrameNum);
+
+ return stat;
+
+ }
+
+
+
+EXPORT_C TInt CFrameTable::FindFrameTimeFromPos(TUint& aTimeMs, TUint& aPos)
+
+ {
+
+ DP1(_L("CFrameTable::FindFrameTimeFromPos pos[%u]"), aPos);
+
+ TInt stat = KErrNotFound;
+
+ // TBufRefPosEntry temp; // used for array search
+
+ // temp.iFrameNum = 0;
+
+ // temp.iPos = aPos;
+
+
+
+ // stat = iFrameTable.SpecificFindInUnsignedKeyOrder(temp, EArrayFindMode_First);
+
+ TUint count = iFrameTable.Count();
+
+ for (TUint i=0; i<count; i++)
+
+ {
+
+ if (iFrameTable[i].iPos >= aPos)
+
+ {
+
+ stat = i;
+
+ DP4(_L("CFrameTable::FindFrameTimeFromPos hi-res first[%u] last[%u] count[%u] stat[%d]"),
+
+ iFrameTable[0].iPos, iFrameTable[count-1].iPos, count, stat);
+
+ break;
+
+ }
+
+ }
+
+#ifdef _DEBUG
+
+ if(count == 0)
+
+ {
+
+ DP0(_L("CFrameTable::FindFrameTimeFromPos hi-res Frame Table: Empty"));
+
+ }
+
+#endif
+
+
+
+ if (stat == KErrNotFound)
+
+ {
+
+ // stat = iLowResFrameTable.SpecificFindInUnsignedKeyOrder(temp, EArrayFindMode_First);
+
+ count = iLowResFrameTable.Count();
+
+ for (TUint i=0; i<count; i++)
+
+ {
+
+ if (iLowResFrameTable[i].iPos >= aPos)
+
+ {
+
+ stat = i;
+
+ DP4(_L("CFrameTable::FindFrameTimeFromPos lo-res first[%u] last[%u] count[%u] stat[%d]"),
+
+ iLowResFrameTable[0].iPos, iLowResFrameTable[count-1].iPos, count, stat);
+
+ break;
+
+ }
+
+ }
+
+#ifdef _DEBUG
+
+ if(count == 0)
+
+ {
+
+ DP0(_L("CFrameTable::FindFrameTimeFromPos lo-res Frame Table: Empty"));
+
+ }
+
+#endif
+
+
+
+ if (stat != KErrNotFound)
+
+ {
+
+ aPos = iLowResFrameTable[stat].iPos;
+
+ aTimeMs = iLowResFrameTable[stat].iFrameNum * iMsecPerFrame;
+
+ iFrameNum = iLowResFrameTable[stat].iFrameNum; // iFrameNum provides frame num after hi-res table is reset
+
+ DP3(_L("CFrameTable::FindFrameTimeFromPos lo-res iFrameNum[%u] indx[%d] iFrameNum sync[%u]"), iLowResFrameTable[stat].iFrameNum, stat, iFrameNum);
+
+ }
+
+ }
+
+ else
+
+ {
+
+ aPos = iFrameTable[stat].iPos;
+
+ aTimeMs = iFrameTable[stat].iFrameNum * iMsecPerFrame;
+
+ iFrameNum = iFrameTable[stat].iFrameNum; // iFrameNum provides frame num after hi-res table is reset
+
+ DP3(_L("CFrameTable::FindFrameTimeFromPos hi-res iFrameNum[%u] indx[%d] iFrameNum sync[%u]"), iFrameTable[stat].iFrameNum, stat, iFrameNum);
+
+ }
+
+
+
+ DP3(_L("CFrameTable::FindFrameTimeFromPos time[%u] pos[%u] indxstat[%d]"), aTimeMs, aPos, stat);
+
+ if (stat> 0)
+
+ {
+
+ stat = KErrNone;
+
+ }
+
+ return stat;
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::LastFramePos
+
+// -----------------------------------------------------------------------------
+
+//
+
+EXPORT_C TInt CFrameTable::LastFramePos(TUint& aPos)
+
+ {
+
+ TInt stat = KErrNotFound;
+
+ TInt stat1 = KErrNotFound;
+
+ TInt stat2 = KErrNotFound;
+
+ TUint count;
+
+ TInt pos1 = 0;
+
+ TInt pos2 = 0;
+
+
+
+ count = iFrameTable.Count();
+
+ DP1(_L("CFrameTable::LastFramePos count[%u]"), count);
+
+ if (count> 0)
+
+ {
+
+ pos1 = iFrameTable[count-1].iPos;
+
+ stat1 = KErrNone;
+
+ DP1(_L("CFrameTable::LastFramePos last pos in hi-res[%d]"), pos1);
+
+ }
+
+
+
+ count = iLowResFrameTable.Count();
+
+ DP1(_L("CFrameTable::LastFramePos lr count[%u]"), count);
+
+ if (count> 0)
+
+ {
+
+ pos2 = iLowResFrameTable[count-1].iPos;
+
+ stat2 = KErrNone;
+
+ DP1(_L("CFrameTable::LastFramePos last pos in low-res[%d]"), pos2);
+
+ }
+
+
+
+ if ((stat1 == KErrNone) && (stat2 == KErrNone))
+
+ {
+
+ aPos = Max(pos1, pos2);
+
+ stat = KErrNone;
+
+ }
+
+ else if (stat1 == KErrNone)
+
+ {
+
+ aPos = pos1;
+
+ stat = KErrNone;
+
+ }
+
+ else if (stat2 == KErrNone)
+
+ {
+
+ aPos = pos2;
+
+ stat = KErrNone;
+
+ }
+
+ DP1(_L("CFrameTable::LastFramePos aPos[%d]"), aPos);
+
+
+
+ return stat;
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::LastFrameTime
+
+// -----------------------------------------------------------------------------
+
+//
+
+EXPORT_C TInt CFrameTable::LastFrameTime(TUint& aTimeMs)
+
+ {
+
+ DP0(_L("CFrameTable::LastFrameTime"));
+
+ TInt stat = KErrNotFound;
+
+ TInt stat1 = KErrNotFound;
+
+ TInt stat2 = KErrNotFound;
+
+ TUint count;
+
+ TUint frameNum = 0;
+
+ TInt frameNum1 = 0;
+
+ TInt frameNum2 = 0;
+
+
+
+ count = iFrameTable.Count();
+
+ if (count> 0)
+
+ {
+
+ frameNum1 = iFrameTable[count-1].iFrameNum;
+
+ stat1 = KErrNone;
+
+ }
+
+
+
+ count = iLowResFrameTable.Count();
+
+ if (count> 0)
+
+ {
+
+ frameNum2 = iLowResFrameTable[count-1].iFrameNum;
+
+ stat2 = KErrNone;
+
+ }
+
+
+
+ if ((stat1 == KErrNone) && (stat2 == KErrNone))
+
+ {
+
+ frameNum = Max(frameNum1, frameNum2);
+
+ stat = KErrNone;
+
+ }
+
+ else if (stat1 == KErrNone)
+
+ {
+
+ frameNum = frameNum1;
+
+ stat = KErrNone;
+
+ }
+
+ else if (stat2 == KErrNone)
+
+ {
+
+ frameNum = frameNum2;
+
+ stat = KErrNone;
+
+ }
+
+
+
+ aTimeMs = frameNum * iMsecPerFrame;
+
+ DP2(_L("CFrameTable::LastFrameTime time[%u] frame[%u]"),aTimeMs,frameNum);
+
+
+
+ return stat;
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::ResetTable
+
+// -----------------------------------------------------------------------------
+
+//
+
+EXPORT_C void CFrameTable::ResetTable()
+
+ {
+
+ DP0(_L("CFrameTable::ResetTable"));
+
+
+
+ iFrameTable.Reset();
+
+ iBufCnt = 0;
+
+ iOkToShrink = EFalse;
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::ShrinkTable
+
+// -----------------------------------------------------------------------------
+
+//
+
+EXPORT_C void CFrameTable::ShrinkTable()
+
+ { // gets called from controller decoder when switching to next buffer
+
+ DP0(_L("CFrameTable::ShrinkTable"));
+
+ if (iBufCnt < KBuffersToKeep)
+
+ {
+
+ iBufCnt++;
+
+ }
+
+ else
+
+ {
+
+ iOkToShrink = ETrue;
+
+ DP0(_L("CFrameTable::ShrinkTable ok to shrink"));
+
+ }
+
+ }
+
+
+
+EXPORT_C TInt CFrameTable::SetSourceReference(TUint aTimeMs, TUint aPos)
+
+ { // if position is unknown it should always be set to 0 as the reference offset and time will be used instead
+
+ // This is used to set the offset which is added to future frame positions submitted
+
+ // This frame table can get reset when seeking and needs to know where it is in the source
+
+ DP2(_L("CFrameTable::SetOffset, aTimeMs[%u], aPos[%u]"), aTimeMs, aPos);
+
+ TInt stat = KErrNone;
+
+ iTimeRefMs = aTimeMs;
+
+ iCurrentFrameCount = 0;
+
+ iIntervalRef = 0;
+
+ iOffset = aPos;
+
+ if (aTimeMs == 0)
+
+ {
+
+ iFrameNum = 0;
+
+ }
+
+ if (iFrameTable.Count() == 0)
+
+ { // this is to make sure the table has at least one entry in case playback looks for a position in the buffers after seeking
+
+ SubmitTableEntry(0);
+
+ // iCurrentFrameCount--; // since this is not a decoded frame
+
+ }
+
+ return stat;
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::RegisterForEvent
+
+// -----------------------------------------------------------------------------
+
+//
+
+EXPORT_C TInt CFrameTable::RegisterForEvent(TFrameTableEvent aEvent,
+
+ MFrameTableEventObserver* aObserver,
+
+ TUint aParam)
+
+ {
+
+ DP2(_L("CFrameTable::RegisterForEvent event[%d] param[%u]"), aEvent, aParam);
+
+
+
+ TInt status = KErrNone;
+
+ iObserver = aObserver;
+
+
+
+ switch (aEvent)
+
+ {
+
+ case EPosReached:
+
+ iPosEventMs = aParam;
+
+ break;
+
+
+
+ case EPlayWindowEndPosReached:
+
+ iPlayWindowEndPosEventMs = aParam;
+
+ break;
+
+
+
+ case EDecodeInterval:
+
+
+
+ if (aParam> 0) // msec
+
+
+
+ {
+
+ iIntervalRef = 0;
+
+ iIntervalEvent = aParam;
+
+ }
+
+ else
+
+ return KErrArgument;
+
+
+
+ break;
+
+
+
+ default:
+
+ status = KErrUnknown;
+
+ break;
+
+ }
+
+
+
+ return status;
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::UnRegisterForEvent
+
+// -----------------------------------------------------------------------------
+
+//
+
+EXPORT_C TInt CFrameTable::UnRegisterForEvent(TFrameTableEvent aEvent, MFrameTableEventObserver* /*aObserver*/)
+
+ {
+
+ DP1(_L("CFrameTable::UnRegisterForEvent event[%d]"), aEvent);
+
+
+
+ TInt status = KErrNone;
+
+
+
+ switch (aEvent)
+
+ {
+
+ case EPosReached:
+
+ iPosEventMs = 0;
+
+ break;
+
+
+
+ case EPlayWindowEndPosReached:
+
+ iPlayWindowEndPosEventMs = 0;
+
+ break;
+
+
+
+ case EDecodeInterval:
+
+ iIntervalEvent = 0;
+
+ break;
+
+
+
+ default:
+
+ status = KErrUnknown;
+
+ break;
+
+ }
+
+
+
+ return status;
+
+ }
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::Bitrate
+
+// -----------------------------------------------------------------------------
+
+//
+
+EXPORT_C TInt CFrameTable::Bitrate()
+
+ {
+
+ return iAvgBitrate;
+
+ }
+
+
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+
+
+// -----------------------------------------------------------------------------
+
+// CFrameTable::CalcFrameFromTimeMs
+
+// -----------------------------------------------------------------------------
+
+//
+
+TUint CFrameTable::CalcFrameFromTimeMs(TUint aTimeMs)
+
+ { // TUint in msec can represent 1193 hours
+
+ TUint frame = 0;
+
+
+
+ if (iMsecPerFrame > 0)
+
+ {
+
+ frame = aTimeMs/iMsecPerFrame;
+
+ }
+
+
+
+ return frame;
+
+ }
+
+
+
+EXPORT_C TInt CFrameTable::IsSeeking(TBool& aIsSeeking)
+
+ {
+
+ aIsSeeking = (iPosEventMs> 0);
+
+ return KErrNone;
+
+ }
+
+
+
+EXPORT_C TInt CFrameTable::GetLastPosEvent(TUint& aPos)
+
+ {
+
+ aPos = iEventPos;
+
+ return KErrNone;
+
+ }
+
+
+
+// End of File
+
+
+