From xiaolin.lliu at nokia.com  Tue Sep  7 11:53:56 2010
From: xiaolin.lliu at nokia.com (xiaolin.lliu@nokia.com)
Date: Tue Sep  7 18:19:29 2010
Subject: [Helix-client-dev] [datatype-dev] [Client-dev] [Clientapps-dev] CR:
 Symbian Add Power Save Support to Brizo420 and head
In-Reply-To: 
References: 
	
Message-ID: 

Skipped content of type multipart/alternative-------------- next part --------------

Index: mdfauddevice.h
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfauddevice.h,v
retrieving revision 1.10.10.1
diff -u -r1.10.10.1 mdfauddevice.h
--- mdfauddevice.h	9 Feb 2010 17:55:23 -0000	1.10.10.1
+++ mdfauddevice.h	31 Aug 2010 19:44:43 -0000
@@ -70,6 +70,10 @@
 #include "mdfaudfmt.h"
 #include "mdfauddata.h"
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxTimelineLimit.h"
+#include  "hxPowerSave.h"
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 // mdf device uses invalid value for initialization
 #define MDFDEVICE_INVALID_VOLUME -1 
 
@@ -80,6 +84,11 @@
                             public CActive,
                             public CHXMDFAudioDeviceObserver,
                             public IHXPropWatchResponse
+#ifdef HELIX_FEATURE_POWER_SAVE
+                           ,public IHXPowerSave
+                           ,public IHXTimeLineLimit
+                           ,public CHXPowerSaveAudDeviceObserver
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 {
 public:
     // factory method
@@ -148,7 +157,28 @@
     void SetStreamFinished(HXBOOL bEndOfStream);
 
     void StreamFinished();
-
+#ifdef HELIX_FEATURE_POWER_SAVE
+	/*Implement IHXTimeLineLimit*/
+    STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs );
+    STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs );
+    STDMETHOD(ResetLimit) (THIS);
+
+    /*Implement IHXPowerSave*/
+    STDMETHOD(StartPowerSave) (THIS);
+    STDMETHOD(EndPowerSave ) (THIS);
+    STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
+    STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
+    STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
+    STDMETHODIMP SetWakeUpInterval(THIS_ ULONG32 ulWakeUpInterval );
+    //
+    // CHXPowerSaveAudDeviceObserver methods
+    //
+    virtual void HighWaterMark();
+    virtual void LowWaterMark();
+protected:
+    HXBOOL IsDueStreamLimit();
+    void LoadPowerSaveCfg();
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 private:
     CHXMDFAudioDevice(HXMDFAudioFormat* pAudioFormat);      //constructor
     HX_RESULT Construct();          //two-phase constructor
@@ -179,6 +209,8 @@
 
     //Timing
     UINT32              m_ulAudioTimeOffset;    //rendering time
+    UINT32              m_ulCurrPlayTime;
+    HXBOOL              m_bDisableOnTimeSyncTimer;
         
     // buffered frames
     CHXSimpleList       m_bufferList;           //frames received from decoder
@@ -206,6 +238,24 @@
 
     HXBOOL              m_bEndOfStream; 
     HXBOOL              m_bEndOfStreamSent; 
+#ifdef HELIX_FEATURE_POWER_SAVE
+private:
+    IHXScheduler3*	m_pScheduler3;
+    HXBOOL m_bIsInPowerSave;
+    UINT32 m_ulWakeUpInterval;
+    UINT32 m_ulLowWaterMark;
+    UINT32 m_ulLimitDeviceInMs;
+    //last packet time passed to mdfDevsound Q
+    UINT32 m_ulLastAudioWrite;
+
+    //  Stat for power save config
+    UINT32 m_ulSchedulerPausedTime;
+    UINT32 m_ulSchedulerResumedTime;
+    UINT32 m_ulTotalSchedSleepTime;
+    UINT32 m_ulTotalSchedRunTime;
+
+
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 };
 
 ------------------------------------------------------------------------------------------------------------------

Index: mdfauddevice.cpp
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfauddevice.cpp,v
retrieving revision 1.19.4.7
diff -u -r1.19.4.7 mdfauddevice.cpp
--- mdfauddevice.cpp	8 Jun 2010 08:40:06 -0000	1.19.4.7
+++ mdfauddevice.cpp	31 Aug 2010 20:05:03 -0000
@@ -50,9 +50,15 @@
 #include "hxassert.h"
 #include "mdfauddevice.h"
 #include "mdfdebug.h"
+#include "hxtick.h" //HX_GET_BETTERTICKCOUNT()
 #include "hxprefutil.h"
 #include "hal.h" // for HAL::Get of ENanoTickPeriod
 
+#define DEFAULT_POWER_SAVE_HWM_MS   6000 //values are set in ms
+#define DEFAULT_POWER_SAVE_LWM_MS   2000 //values are set in ms
+// Offset is added to the HWM when wakeupinterval is calculated
+#define POWER_SAVE_HWM_OFFSET_MS       500
+
 
 static UINT32 Scale(UINT32 v, UINT32 f0, UINT32 f1, UINT32 t0, UINT32 t1);
 
@@ -122,6 +128,8 @@
         m_nBytesPCMToPlay(0),
         m_playing(FALSE),
         m_ulAudioTimeOffset(0),
+        m_ulCurrPlayTime(0),
+        m_bDisableOnTimeSyncTimer(FALSE),
         m_pAudioFormat(pAudioFormat),
         m_pErrorMessage(NULL),
         m_bDevTimeNeeded(TRUE),
@@ -132,6 +140,18 @@
         m_pPropWatch(NULL),
         m_bEndOfStream(FALSE)
         ,m_bEndOfStreamSent(FALSE)
+#ifdef HELIX_FEATURE_POWER_SAVE
+        ,m_pScheduler3(NULL)
+        ,m_bIsInPowerSave(FALSE)
+        ,m_ulWakeUpInterval (DEFAULT_POWER_SAVE_HWM_MS)
+        ,m_ulLowWaterMark(DEFAULT_POWER_SAVE_LWM_MS)
+        ,m_ulLimitDeviceInMs (0)
+        ,m_ulLastAudioWrite(0)
+        ,m_ulSchedulerPausedTime(0)
+        ,m_ulSchedulerResumedTime(HX_GET_BETTERTICKCOUNT())
+        ,m_ulTotalSchedSleepTime(0)
+        ,m_ulTotalSchedRunTime(0)
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 {
     //- activate active object
     CActiveScheduler::Add(this);
@@ -152,6 +172,18 @@
 CHXMDFAudioDevice::~CHXMDFAudioDevice()
 {
     HXLOGL4(HXLOG_MDFA,"mdfdev:~mdfdev <");
+#ifdef HELIX_FEATURE_POWER_SAVE
+    m_ulSchedulerPausedTime = HX_GET_BETTERTICKCOUNT();
+    UINT32 ulCurrSchedRunTime = m_ulSchedulerPausedTime - m_ulSchedulerResumedTime;
+    m_ulTotalSchedRunTime += ulCurrSchedRunTime;
+    UINT32 ulTotalSchedTime = m_ulTotalSchedRunTime + m_ulTotalSchedSleepTime;
+    HXLOGL1(HXLOG_MDFA,"------ Statistics of Power Save ----------");
+    HXLOGL1(HXLOG_MDFA, "CHXMDFAudioDevice[%p]::~CHXMDFAudioDevice PSave TotalRunTime:%lu TotSleepTime:%lu", this, m_ulTotalSchedRunTime, m_ulTotalSchedSleepTime);
+    HXLOGL1(HXLOG_MDFA, "CHXMDFAudioDevice[%p]::~CHXMDFAudioDevice PSave TotalRunTime:%lu Percent TotSleepTime:%lu percent", this,
+        ((m_ulTotalSchedRunTime *100 /ulTotalSchedTime)) , ((m_ulTotalSchedSleepTime*100 /ulTotalSchedTime)) );
+    HXLOGL1(HXLOG_MDFA,"------------------------------------------");
+    HX_RELEASE(m_pScheduler3);
+#endif // End of #ifdef HELIX_FEATURE_POWER_SAVE
     Close(TRUE);
     m_iTimer.Close();
 
@@ -209,6 +241,10 @@
             { GET_IIDHANDLE(IID_IHXTimelineWatcher), (IHXTimelineWatcher*)this },
             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXAudioDevice*)this },
             { GET_IIDHANDLE(IID_IHXPropWatchResponse), (IHXPropWatchResponse*)this },
+#ifdef HELIX_FEATURE_POWER_SAVE
+            { GET_IIDHANDLE(IID_IHXTimeLineLimit), (IHXTimeLineLimit*)this },
+            { GET_IIDHANDLE(IID_IHXPowerSave), (IHXPowerSave*)this },
+#endif /*HELIX_FEATURE_POWER_SAVE*/
         };
 
     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
@@ -295,6 +331,9 @@
         HX_RELEASE(m_pErrorMessage);
         m_pContext->QueryInterface(IID_IHXErrorMessages, (void **)&m_pErrorMessage);
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+        LoadPowerSaveCfg();
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
     }
     else
     {
@@ -351,8 +390,8 @@
 
 			m_bDevTimeNeeded = TRUE;	//now we need Dev Time
 				
-            GetCurrentAudioTime(ulAudioTime);
-            m_pDeviceResponse->OnTimeSync(ulAudioTime);
+            m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+            m_pDeviceResponse->OnTimeSync(m_ulCurrPlayTime);
         }
 
         //Set timer for next OnTimeSync callback
@@ -564,8 +603,8 @@
     if(m_pDeviceResponse)
     {
         ULONG32 ulAudioTime = 0;
-        GetCurrentAudioTime(ulAudioTime);
-        m_pDeviceResponse->OnTimeSync(ulAudioTime);
+        m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+        m_pDeviceResponse->OnTimeSync(m_ulCurrPlayTime);
     }
 
     DoSetTimer();
@@ -601,6 +640,10 @@
             HXLOGL4(HXLOG_MDFA,"mdfdev:write .. encoded data added");
             m_bufferList.RemoveHead();
             m_readyList.AddTail(pAudioData);
+#if defined HELIX_FEATURE_POWER_SAVE
+            m_ulLastAudioWrite = pAudioData->m_ulAudioTime-m_ulAudioTimeOffset;
+            m_pDevSound->SetLastRecvdEncodedData(m_ulLastAudioWrite);
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 
 #if defined(HELIX_FEATURE_LOGLEVEL_4) || defined(HELIX_FEATURE_LOGLEVEL_ALL)
             if ( pAudioData )
@@ -615,11 +658,12 @@
     {
         m_nBytesPCMToPlay += dataSize;
         
-        while(m_nBytesPCMToPlay >= m_pAudioFormat->m_uBytesPerFrame && m_pAudioFormat->m_uBytesPerFrame)
+        while(m_nBytesPCMToPlay >= m_pAudioFormat->m_uBytesPerFrame && m_pAudioFormat->m_uBytesPerFrame
+                && m_bEndOfStreamSent) 
         {
             m_readyList.AddTail(&m_pAudioFormat->m_fillerFrame);
             m_nBytesPCMToPlay -= m_pAudioFormat->m_uBytesPerFrame;
-            HXLOGL4(HXLOG_MDFA,"mdfdev:write .. adding filler frame");
+            HXLOGL4(HXLOG_MDFA,"mdfdev:write .. adding filler frame m_bEndOfStreamSent:%d", m_bEndOfStreamSent);
         }
     }
 
@@ -708,6 +752,7 @@
     //reset SecureOutput settings
     m_bSecureOutputChanged = FALSE;
 
+    m_ulCurrPlayTime = 0; 
     // stop device.
     if (m_pDevSound)
     {
@@ -767,11 +812,11 @@
 
 	if (pAudioFormat) {
         if (m_pAudioFormat->m_uChannels == pAudioFormat->uChannels &&
-        		m_pAudioFormat->m_uBitsPerSample == pAudioFormat->uBitsPerSample &&
-        		m_pAudioFormat->m_ulSamplesPerSec == pAudioFormat->ulSamplesPerSec) {
+            m_pAudioFormat->m_uBitsPerSample == pAudioFormat->uBitsPerSample &&
+            m_pAudioFormat->m_ulSamplesPerSec == pAudioFormat->ulSamplesPerSec) {
         			res = HXR_OK;
         		}
-    }
+	}
     return res;
 }
 
@@ -784,32 +829,55 @@
 
     HX_RESULT hxr = HXR_OK;
 
-    UINT32 systemTime=(UINT32)(((UINT64)User::NTickCount() * 1000) / m_systemTickPeriodInMicroSecond); 
+  //  UINT32 systemTime=(UINT32)(((UINT64)User::NTickCount() * 1000) / m_systemTickPeriodInMicroSecond); 
 
-    if (m_bDevTimeNeeded) {
-        hxr = m_pDevSound->GetCurrentPlayTime(ulCurrentTime);  //Dev Time
-        m_devTime = ulCurrentTime;
-        if (m_ulLastTime>ulCurrentTime) {
+#ifdef HELIX_FEATURE_POWER_SAVE
+    //  If scheduler is not running, the playback time is not current.
+    //  Update the current playback time
+    if(m_bIsInPowerSave && m_pScheduler3 && m_pScheduler3->IsPaused())
+    {
+        hxr = m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+        ulCurrentTime = m_ulCurrPlayTime;
+    }
+    else	
+#endif 
+    {
+        UINT32 systemTime=(UINT32)(((UINT64)User::NTickCount() * 1000) / m_systemTickPeriodInMicroSecond); 
+        if (m_bDevTimeNeeded)             
+        {
+            hxr = m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);  //Dev Time
+            ulCurrentTime = m_ulCurrPlayTime;
+            m_devTime = ulCurrentTime;
+            if (m_ulLastTime>ulCurrentTime) 
+            {
             // Device time ahead of computed time:
             //   return last computed time
-            ulCurrentTime=m_ulLastTime;
-        }
-        m_systemTimeMark = systemTime;
-        m_bDevTimeNeeded = FALSE;				//no need to check Dev Time.
-    } else {
-        // Don't ask time to device: compute using elapsed system time
-        LONG32 elapse = systemTime - m_systemTimeMark;
-        // Case of 32 bit counter overflow
-        if (elapse < 0) elapse= -elapse;
-        ulCurrentTime = m_devTime + elapse;		//interpolation
-        if (m_ulLastTime>ulCurrentTime) {
+                ulCurrentTime=m_ulLastTime;
+            }
+            m_systemTimeMark = systemTime;
+            m_bDevTimeNeeded = FALSE;				//no need to check Dev Time.
+        } 
+        else 
+        {
+            // Don't ask time to device: compute using elapsed system time
+            LONG32 elapse = systemTime - m_systemTimeMark;
+            // Case of 32 bit counter overflow
+            if (elapse < 0) elapse= -elapse;
+            ulCurrentTime = m_devTime + elapse;		//interpolation xaliu
+
+            if (m_ulLastTime>ulCurrentTime) 
+			{
             // New computed time still behind last computed time:
             //   return last computed time until new computed time goes ahead
-            ulCurrentTime=m_ulLastTime;
-        } else {
-            m_ulLastTime=ulCurrentTime;
-        }
-     } 
+                ulCurrentTime=m_ulLastTime;
+            } 
+            else 
+            {
+                m_ulLastTime=ulCurrentTime;
+            }
+        } 
+    }
+
 #if defined(HELIX_FEATURE_DRM_SECURE_OUTPUT)
 	if(m_bSecureOutputChanged) 
 	{
@@ -893,6 +961,7 @@
     HXLOGL4(HXLOG_MDFA,"mdfdeV:setStartT <> %d", ulStartTime);
 
     m_ulAudioTimeOffset = ulStartTime;
+    m_pDevSound->SetAudioTimeOffset(m_ulAudioTimeOffset); 
 }
 
 void CHXMDFAudioDevice::SetStreamFinished(HXBOOL bEndOfStream)
@@ -935,7 +1004,7 @@
 {
     HXLOGL4(HXLOG_MDFA,"mdfdeV:dosettimer <");
 
-    if( !IsActive())
+    if( (!IsActive()) && (!m_bDisableOnTimeSyncTimer)) 
     {
         //HXLOGL4(HXLOG_MDFA, "mdfdeV:dosettimer .. set timer here. %d", iStatus.Int());
         m_iTimer.After(iStatus, m_TimeSyncPeriodInMs * 1000);
@@ -953,7 +1022,9 @@
     HXLOGL4(HXLOG_MDFA, "mdfdeV:OnDeviceError <");
 
     HX_ASSERT(m_pErrorMessage != NULL);
-
+#ifdef HELIX_FEATURE_POWER_SAVE
+    EndPowerSave();
+#endif /*HELIX_FEATURE_POWER_SAVE*/
     // Report error to Error Messages
     if(m_pErrorMessage)
     {
@@ -1014,6 +1085,227 @@
 }
 
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+void CHXMDFAudioDevice::LoadPowerSaveCfg()
+{
+    if(m_pContext != NULL)
+    {
+        IHXPreferences* pPreference = NULL;
+        if(SUCCEEDED(m_pContext->QueryInterface(IID_IHXPreferences, (void**) &pPreference)))
+        {
+            // High water mark is same as wake up interval
+            UINT32 hwm = 0;
+            UINT32 lwm = 0;
+            if (SUCCEEDED(ReadPrefUINT32(pPreference, "PowerSaveHWM", hwm)) 
+                    && SUCCEEDED(ReadPrefUINT32(pPreference, "PowerSaveLWM", lwm)))            
+            {
+                if (lwm < hwm)
+                {
+                    m_ulWakeUpInterval = hwm;
+                    m_ulLowWaterMark = lwm;
+                }
+            }
+            HX_RELEASE(pPreference);
+        }
+    }
+    HXLOGL2(HXLOG_MDFA, "mdfdeV:LoadPowerSaveCfg HWM:%lu LWM:%lu ", m_ulWakeUpInterval, m_ulLowWaterMark);
+}
+HXBOOL CHXMDFAudioDevice::IsDueStreamLimit()
+{
+    HXBOOL bReachingStreamLimit = FALSE;
+    if((m_bIsInPowerSave) && m_ulLimitDeviceInMs != 0)
+    {
+        ULONG32 ulAudioTime = 0;
+        GetCurrentAudioTime(ulAudioTime);
+        //get the time left
+        ulAudioTime = (ULONG32)m_ulLimitDeviceInMs - ulAudioTime;
+
+        //if we are reaching the end of file
+        if( ulAudioTime < (ULONG32)m_ulWakeUpInterval)
+        {
+            bReachingStreamLimit = TRUE;
+        }
+    }
+
+    HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::IsDueStreamLimit bReachingStreamLimit[%d] ", this, bReachingStreamLimit);
+
+    return bReachingStreamLimit;
+}
+STDMETHODIMP
+CHXMDFAudioDevice::SetLimit (UINT32 ulLimitInMs )
+{
+    m_ulLimitDeviceInMs = ulLimitInMs;
+
+    HX_RESULT retVal = HXR_OK;
+    HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::SetLimit retVal=%x ", this, retVal);
+    return retVal;
+}
+
+STDMETHODIMP
+CHXMDFAudioDevice::GetLimit (UINT32 &ulLimitInMs )
+{
+   ulLimitInMs = m_ulLimitDeviceInMs;
+
+   HX_RESULT retVal = HXR_OK;
+   HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::GetLimit retVal=%x ", this, retVal);
+   return retVal;
+}
+
+STDMETHODIMP
+CHXMDFAudioDevice::ResetLimit ()
+{
+    m_ulLimitDeviceInMs = 0;
+
+    return HXR_OK;
+}
+
+
+/*Implement IHXPowerSave*/
+STDMETHODIMP
+CHXMDFAudioDevice::StartPowerSave()
+{
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::StartPowerSave ", this);
+
+    HX_RESULT retVal = HXR_OK;
+    if(!m_bIsInPowerSave)
+    {
+        HX_RELEASE(m_pScheduler3);
+        retVal = m_pContext->QueryInterface(IID_IHXScheduler3, (void**) &m_pScheduler3);
+
+        if(m_pScheduler3 != NULL)
+        {
+            //set value to true for active
+            m_bIsInPowerSave = TRUE;
+            m_pDevSound->SetPowerSaveConfig((CHXPowerSaveAudDeviceObserver*)this, m_ulWakeUpInterval, m_ulLowWaterMark);
+        } // End of if(m_pScheduler3 != NULL)
+        else 
+        {
+            HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::StartPowerSave Can not query Scheduler3");
+            retVal = HXR_FAIL;
+        }
+    }
+
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::StartPowerSave retVal=%x ", this, retVal);
+
+    return retVal;
+}
+
+
+STDMETHODIMP
+CHXMDFAudioDevice::EndPowerSave()
+{
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::EndPowerSave ", this);
+
+    HX_RESULT retVal = HXR_OK;
+    if(m_bIsInPowerSave)
+    {
+        HXLOGL3( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::EndPowerSave calling ResumeScheduler ", this);
+        LowWaterMark();
+        m_pDevSound->SetPowerSaveConfig(NULL, m_ulWakeUpInterval, m_ulLowWaterMark); //as such LowWaterMArk won't be called
+        m_bIsInPowerSave = FALSE;
+
+    } // End of if(m_bIsInPowerSave)
+
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::EndPowerSave retVal=%x ", this, retVal);
+
+    return retVal;
+}
+STDMETHODIMP_(HXBOOL)
+CHXMDFAudioDevice::IsInPowerSave()
+{
+    HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::IsInPowerSave m_bIsInPowerSave=%d ", this, m_bIsInPowerSave);
+    return m_bIsInPowerSave;
+}
+
+STDMETHODIMP_(HXBOOL)
+CHXMDFAudioDevice::CanStartPowerSave()
+{
+    HXBOOL bCanStart = TRUE;
+    HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::CanStartPowerSave bCanStart:%d", this, bCanStart);
+    return bCanStart;
+}
+
+STDMETHODIMP_(ULONG32)
+CHXMDFAudioDevice::GetWakeUpInterval()
+{
+    ULONG32 ulWakeUpInterval = m_ulWakeUpInterval;
+    // Adding an offset, so that the source does not stop sending data based on old playback time.
+    ulWakeUpInterval += POWER_SAVE_HWM_OFFSET_MS;
+    HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::GetWakeUpInterval m_ulWakeUpInterval=%lu ", this, m_ulWakeUpInterval);
+
+    return ulWakeUpInterval;
+}
+STDMETHODIMP 
+CHXMDFAudioDevice::SetWakeUpInterval(ULONG32 ulWakeUpInterval )
+{
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::SetWakeUpInterval --WARNING-- luWakeUpInterval=%lu", this, ulWakeUpInterval);
+	//
+    // Does not accept other values from core
+    //
+    return HXR_FAIL;	
+}
+void CHXMDFAudioDevice::HighWaterMark()
+{
+    if(m_bIsInPowerSave)
+    {
+        HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::HighWaterMark calling IsDueStreamLimit()", this);
+
+        //when reaching the end of file we don't want to go to sleep
+        if(!IsDueStreamLimit())
+        {
+            if( !m_pScheduler3->IsPaused() )
+            {
+                m_ulSchedulerPausedTime = HX_GET_BETTERTICKCOUNT();
+                UINT32 ulCurrSchedRunTime = m_ulSchedulerPausedTime - m_ulSchedulerResumedTime;
+                m_ulTotalSchedRunTime += ulCurrSchedRunTime;
+                HXLOGL2( HXLOG_MDFA, "CHXAudioDevice[%p]::HighWaterMark PSave PauseScheduler RunTime:%lu TotRun:%lu", this, ulCurrSchedRunTime, m_ulTotalSchedRunTime);
+                m_pScheduler3->PauseScheduler();
+            }
+
+            m_bDisableOnTimeSyncTimer = TRUE;
+			m_bDevTimeNeeded = TRUE;
+
+            // Cancel the timer used for ontimesync reporting
+            if (IsActive())
+            {
+                HXLOGL3( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::Calling cancel ", this);
+                Cancel();
+            }
+        } // End of if(!IsDueStreamLimit())
+    } // End of if(m_bIsInPowerSave)
+
+}
+
+
+void CHXMDFAudioDevice::LowWaterMark()
+{
+    HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::LowWaterMark m_bIsInPowerSave:%d ", this, m_bIsInPowerSave);
+
+    if(m_bIsInPowerSave)
+    {
+        if( m_pScheduler3->IsPaused() )
+        {
+            m_ulSchedulerResumedTime = HX_GET_BETTERTICKCOUNT();
+            UINT32 ulCurrSchedSleepTime = m_ulSchedulerResumedTime - m_ulSchedulerPausedTime;
+            m_ulTotalSchedSleepTime += ulCurrSchedSleepTime;
+            HXLOGL2( HXLOG_MDFA, "CHXAudioDevice[%p]::LowWaterMark PSave ResumeScheduler PauseTime:%lu TotPause:%lu", this, ulCurrSchedSleepTime, m_ulTotalSchedSleepTime);
+
+            m_pScheduler3->ResumeScheduler();
+        }
+
+        //set timer for OntimeSync or unpause timer for ontimesync
+        m_bDisableOnTimeSyncTimer = FALSE;
+        m_bDevTimeNeeded = TRUE;
+        if( !IsActive())
+        {
+            m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+            HXLOGL3( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::LowWaterMark calling SetActive ", this);
+            DoSetTimer();
+        }
+    } // End of if(m_bIsInPowerSave)
+}
+
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 //
 // convenience methods
 //

--------------------------------------------------------------------------------------------------------------------


Index: mdfdevsound.h
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfdevsound.h,v
retrieving revision 1.17.4.2
diff -u -r1.17.4.2 mdfdevsound.h
--- mdfdevsound.h	4 May 2010 08:16:41 -0000	1.17.4.2
+++ mdfdevsound.h	31 Aug 2010 19:20:51 -0000
@@ -62,6 +62,10 @@
 #include "mdfdevconfig.h"
 #include "CHXAudioOutputConfigUtil.h"
 
+//***************************************************************//
+//For the power save mode
+class CHXPowerSaveAudDeviceObserver;
+//***************************************************************//
 class CHXMDFAudioDevice;
 class CHXMDFAudioDeviceObserver;
 class CHXMMFDevSound;
@@ -142,6 +146,13 @@
     
         // helper
         void SetAudioDeviceObserver(CHXMDFAudioDeviceObserver* p) {m_pDevObserver=p;};
+    //for power save
+        void SetPowerSaveConfig(CHXPowerSaveAudDeviceObserver* pPowSaveAudDevObserver, const UINT32& ulHighWaterMark, const UINT32& ulLowWaterMark);
+        void CheckForLWM();
+        void CheckForHWM();
+        void GetTotalUnPlayedDataInMs( UINT32& ulUnPlayedData);
+        void SetLastRecvdEncodedData(const UINT32& ulLastAudioWrite);
+        void SetAudioTimeOffset(UINT32 ulAudioTimeOffset) {m_ulAudioTimeOffset = ulAudioTimeOffset;}
         
     private:
         // constructor
@@ -206,6 +217,16 @@
         // status observer. only one in this implementation
         CHXMDFAudioDeviceObserver*     m_pDevObserver;
         
+    private:
+	
+        UINT32 m_ulHighWaterMark;
+        UINT32 m_ulLowWaterMark;
+        UINT32 m_ulLastEncodedWriteTime;
+        UINT32 m_ulLastDevWriteTime;
+        UINT32 m_ulAudioTimeOffset;
+        HXBOOL m_bDetectedHWM;
+        CHXPowerSaveAudDeviceObserver*     m_pPowSaveAudDevObserver;
+        
     // methods for FourCC            
     private:
 #ifdef _DEBUG_TEST_AUDIO_DEVICE_TAKEN_
@@ -231,4 +252,10 @@
         virtual void OnDeviceError(HX_RESULT hxr) = 0;
 };
 
+class CHXPowerSaveAudDeviceObserver
+{
+    public:
+        virtual void HighWaterMark() = 0;
+        virtual void LowWaterMark() = 0;
+};
 #endif


--------------------------------------------------------------------------------------------------------------------


Index: mdfdevsound.cpp
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfdevsound.cpp,v
retrieving revision 1.28.4.5
diff -u -r1.28.4.5 mdfdevsound.cpp
--- mdfdevsound.cpp	6 May 2010 03:34:26 -0000	1.28.4.5
+++ mdfdevsound.cpp	31 Aug 2010 19:37:50 -0000
@@ -150,6 +150,13 @@
 #ifdef _DEBUG_TEST_AUDIO_DEVICE_TAKEN_
     		,m_lErrCnt(1)
 #endif 
+            , m_ulHighWaterMark(0)
+            , m_ulLowWaterMark(0)
+            , m_ulLastEncodedWriteTime(0)
+            , m_ulLastDevWriteTime(0)
+            , m_ulAudioTimeOffset(0)
+            , m_pPowSaveAudDevObserver(NULL)
+            ,m_bDetectedHWM(FALSE)
 {
     HX_ASSERT(pFrameList);
     HX_ASSERT(pFormat);
@@ -337,8 +344,11 @@
     m_ulSamplesPlayedOffset = GetValidSamplesPlayed(); //BySamplesPlayed
 
 	//samples played before taken and samples written reset to zero
-	m_ulSamplesPlayedBeforeTaken = 0;
-
+    m_ulSamplesPlayedBeforeTaken = 0;
+    m_ulLastDevWriteTime = 0;
+    m_ulLastEncodedWriteTime = 0;
+    m_ulAudioTimeOffset = 0;
+    m_bDetectedHWM = FALSE;
     
     HXLOGL2(HXLOG_MDFA, "---devsnd:reset .. before flush %lu", (UINT32)m_ulSamplesPlayedOffset);
 
@@ -351,8 +361,10 @@
     {
         HX_ASSERT(m_pAddedDevSoundCI);
 		m_devStatus = DevPaused;
-        lError = m_pAddedDevSoundCI->PauseAndFlush();
-
+        if(m_pAddedDevSoundCI != NULL)
+        {
+            lError = m_pAddedDevSoundCI->PauseAndFlush();
+        }
         if (lError!=KErrNone) return HXR_FAIL;
 
     #if defined(HELIX_FEATURE_LOGLEVEL_4)
@@ -412,7 +424,7 @@
 {
     PRINTCURRENTSTATE("---devsnd:PLAY <");
 
-    if (m_devStatus == DevPaused)
+    if ((m_devStatus == DevPaused) || (m_devStatus == DevInitialized) )
     {   //resume
         if (m_pDevSoundBuffer)  // we have the dev buffer
         {
@@ -898,7 +910,6 @@
     }
 
     // -- Start playback loop --
-    StartPlayback();
 
     HXLOGL4(HXLOG_MDFA, "---devsnd:InitComp > %d", aError);
 }
@@ -948,7 +959,7 @@
     else
     {
         HXMDFAudioData* pAudioData = (HXMDFAudioData*)m_pDataList->GetHead();
-        UINT32 ulDataTime = pAudioData->m_ulAudioTime;
+        m_ulLastDevWriteTime = pAudioData->m_ulAudioTime - m_ulAudioTimeOffset;
 
         HX_RESULT retErr = HXR_OK;
         if (pAudioData->m_bMissing || pAudioData->m_bConcealed)
@@ -1017,6 +1028,7 @@
             m_ulFramesPlayedLastRound = 1;
             m_pDevSoundBuffer = NULL;
             m_pDevSound->PlayData();
+            CheckForLWM(); 
        }
         else
         {
@@ -1144,6 +1156,115 @@
 }
 
 
+//
+//  CMDFDevSound::SetPowerSaveConfig
+// 
+void CMDFDevSound::SetPowerSaveConfig(CHXPowerSaveAudDeviceObserver* pPowSaveAudDevObserver
+											, const UINT32& ulHighWaterMark
+											, const UINT32& ulLowWaterMark)
+{
+    HXLOGL2(HXLOG_MDFA,"CMDFDevSound::SetPowerSaveConfig m_ulHighWaterMark =%d, m_ulLowWaterMark =%d", m_ulHighWaterMark, m_ulLowWaterMark);
+
+    m_ulHighWaterMark = ulHighWaterMark;
+    m_ulLowWaterMark = ulLowWaterMark;
+    m_pPowSaveAudDevObserver = pPowSaveAudDevObserver;
+}
+
+//
+//  CMDFDevSound::SetLastRecvdEncodedData
+//  Timestamp of last encoded frame in Q
+// 
+void CMDFDevSound::SetLastRecvdEncodedData(const UINT32& ulLastAudioWrite)
+{
+    m_ulLastEncodedWriteTime = ulLastAudioWrite;
+    CheckForHWM();
+    HXLOGL4(HXLOG_CORE,"mdfdev:Write .. Obs:%p last buf time:%lu", m_pPowSaveAudDevObserver, ulLastAudioWrite);
+}
+
+//
+//  CMDFDevSound::CheckForHWM
+//  Checks if Q has reached high water mark
+//  and report to the observer
+// 
+void CMDFDevSound::CheckForHWM()
+{
+    //  Check if we have enough data to report
+    //  high water mark
+
+    //  We are not checking for m_bDetectedHWM as this call
+    //  should not happen when it is TRUE
+    //
+    if(m_pPowSaveAudDevObserver != NULL)
+    {
+        UINT32 ulTimeLeft = 0;
+        UINT32 ulTimeInDev = 0;
+
+        // First caluclate the data in Q
+        ulTimeLeft = m_ulLastEncodedWriteTime - m_ulLastDevWriteTime;
+
+        //  We use the last updated samples played
+        //  Inaccuracy could be upto 30msec as it is updated from during
+        //  the ontimesync reporting
+        ulTimeInDev = (m_ulLastValidSamplesPlayed - m_ulSamplesPlayedOffset)  * 1000 / m_pAudioFormat->m_ulSamplesPerSec;
+        ulTimeInDev = m_ulLastDevWriteTime - ulTimeInDev;
+
+        ulTimeLeft += ulTimeInDev;
+
+        HXLOGL4(HXLOG_MDFA,"mdfdev:CheckForHWM .. DataInQ:%lu m_ulLastDevWriteTime:%lu",ulTimeLeft, m_ulLastDevWriteTime);
+        
+        if(ulTimeLeft > m_ulHighWaterMark)
+        {
+            m_pPowSaveAudDevObserver->HighWaterMark();
+            HXLOGL4(HXLOG_MDFA,"devsnd:CheckForHWM .. m_bDetectedHWM=%d", m_bDetectedHWM);
+            m_bDetectedHWM = TRUE;
+        }
+    } // End of if(m_pPowSaveAudDevObserver != NULL)
+}
+
+//
+//  CMDFDevSound::CheckForLWM
+//  Checks if Q is below low water mark
+//  and reports to the observer
+// 
+void CMDFDevSound::CheckForLWM()
+{
+    HXLOGL4(HXLOG_MDFA,"devsnd:CheckForLWM .. m_bDetectedHWM=%d", m_bDetectedHWM);
+    if( (m_pPowSaveAudDevObserver != NULL) && (m_bDetectedHWM) )
+    {
+        UINT32 ulDataInQ = m_ulLastEncodedWriteTime - m_ulLastDevWriteTime;
+
+        HXLOGL4(HXLOG_MDFA,"devsnd:CheckForLWM .. ulDataInQ=%lu", ulDataInQ);
+        // We first check, if data in Q is nearing LWM. 
+        // This will reduce the number of samplesplayed calculation
+        if(ulDataInQ < m_ulLowWaterMark)
+        {
+            UINT32 ulTotalUnplayedDataInMs = 0;
+            // Calculate accurate unplayed samples time
+            GetTotalUnPlayedDataInMs(ulTotalUnplayedDataInMs);
+            HXLOGL4(HXLOG_MDFA,"devsnd:CheckForLWM .. Pending=%lu Obs:%p", ulTotalUnplayedDataInMs, m_pPowSaveAudDevObserver);
+            if(ulTotalUnplayedDataInMs <= m_ulLowWaterMark)
+            {
+                m_pPowSaveAudDevObserver->LowWaterMark();
+                m_bDetectedHWM = FALSE;
+            }
+        } // End of if(ulDataInQ < m_ulLowWaterMark)
+
+    } // End of if( (m_pPowSaveAudDevObserver != NULL) && (!m_bDetectedHWM) )
+}
+
+//
+//  CMDFDevSound::GetTotalUnPlayedDataInMs
+//  Returns the amount of unplayed 
+//  data(including data sent to devsound)
+// 
+void CMDFDevSound::GetTotalUnPlayedDataInMs( UINT32& ulUnPlayedData)
+{
+    UINT32 ulPlayTime = 0;
+    GetCurrentPlayTime(ulPlayTime);
+    ulUnPlayedData = m_ulLastEncodedWriteTime - ulPlayTime;
+}
+
+
 //--------------------
 //  Static Methods
 //--------------------


-------------------------------------------------------------------------------------------------------------------


Index: hxaudply.h
===================================================================
RCS file: /cvsroot/client/audiosvc/pub/hxaudply.h,v
retrieving revision 1.21.78.1
diff -u -r1.21.78.1 hxaudply.h
--- hxaudply.h	18 Sep 2009 04:45:12 -0000	1.21.78.1
+++ hxaudply.h	31 Aug 2010 16:40:29 -0000
@@ -55,6 +55,9 @@
 #include "hxplayvelocity.h"
 #include "hxslist.h"
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxTimelineLimit.h"
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
 // forward decls
 struct IHXAudioPlayerResponse;
 struct IHXAudioStream;
@@ -65,10 +68,6 @@
 struct IHXPreferences;
 struct IHXAudioCrossFade;
 
-#if defined(HELIX_FEATURE_POWER_SAVE)
-_INTERFACE IHXPowerSave;
-#endif // HELIX_FEATURE_POWER_SAVE
-
 typedef struct _HXAudioFormat HXAudioFormat;
 
 class CHXAudioSession;
@@ -99,6 +98,7 @@
 #endif 
 #ifdef HELIX_FEATURE_POWER_SAVE
 		      public IHXPowerSave,
+			  public IHXTimeLineLimit,
 #endif
 		      public IHXAudioCrossFade,
 		      public IHXCallback,
@@ -163,7 +163,8 @@
     
 #if defined(HELIX_FEATURE_POWER_SAVE)
     HXBOOL          m_bInPowerSave;         // Player in power save mode
-    IHXPowerSave*   m_pRendererPowerSave;
+    IHXPowerSave*   m_pPowerSave;
+    UINT32          m_ulLimitInMs;
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
   protected:
@@ -227,15 +228,22 @@
         
 #endif        
 
+protected:
+        void ApplyTimeLineLimit();
+public:	
 #if defined(HELIX_FEATURE_POWER_SAVE)
-    HX_RESULT RetrieveRendererPowerSave();
+	/*Implement IHXTimeLineLimit*/
+    STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs );
+    STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs );
+    STDMETHOD(ResetLimit) (THIS);
+    HX_RESULT RetrievePowerSave();
     /* IHXPowerSave methods */
     STDMETHOD_(HX_RESULT,StartPowerSave)                  ( THIS );
     STDMETHOD_(HX_RESULT,EndPowerSave)                    ( THIS );
     STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
     STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
     STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
-    STDMETHOD_(ULONG32,SetWakeUpInterval)      ( THIS_ ULONG32 /*IN*/ ulWakeUpInterval );
+    STDMETHOD(SetWakeUpInterval)      ( THIS_ ULONG32 ulWakeUpInterval );
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
 ---------------------------------------------------------------------------------------------------------------
 
 Index: hxaudply.cpp
 ===================================================================
 RCS file: /cvsroot/client/audiosvc/hxaudply.cpp,v
 retrieving revision 1.58.12.1
 diff -u -r1.58.12.1 hxaudply.cpp
 --- hxaudply.cpp	18 Sep 2009 04:45:11 -0000	1.58.12.1
 +++ hxaudply.cpp	31 Aug 2010 16:59:36 -0000
 @@ -152,8 +152,9 @@
  ,       m_pLastMappingStream(NULL)
  ,       m_bNewMapStarting(TRUE)    
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -,	    m_bInPowerSave(FALSE)
 -,       m_pRendererPowerSave(NULL)
 +,       m_bInPowerSave(FALSE)
 +,       m_pPowerSave(NULL)
 +,       m_ulLimitInMs(0)
  #endif /*HELIX_FEATURE_POWER_SAVE*/
  {
  #ifdef HELIX_FEATURE_VOLUME
 @@ -253,13 +254,13 @@
      // Delete the inactive clock source queue
      HX_DELETE(m_pInactiveClockSourceQueue);
  
 -    
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -        if(m_pRendererPowerSave)
 -        {
 -            HX_RELEASE(m_pRendererPowerSave);
 -        }
 +    if(m_pPowerSave)
 +    {
 +    	HX_RELEASE(m_pPowerSave);
 +    }
  #endif    
 +
  }
  
  /////////////////////////////////////////////////////////////////////////
 @@ -287,6 +288,9 @@
              , { GET_IIDHANDLE(IID_IHXPlaybackVelocity), (IHXPlaybackVelocity*)this }
  #endif /* #if defined(HELIX_FEATURE_PLAYBACK_VELOCITY) */
              , { GET_IIDHANDLE(IID_IHXClockSourceManager), (IHXClockSourceManager*) this }
 +#if defined(HELIX_FEATURE_POWER_SAVE)
 +            ,{ GET_IIDHANDLE(IID_IHXTimeLineLimit), (IHXTimeLineLimit*) this}
 +#endif
          };
  
      HX_RESULT res = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
 @@ -1482,6 +1486,7 @@
  	{
              theErr = m_Owner->Resume(this, bSessionRewindNeededForStream);
  	}
 +        ApplyTimeLineLimit();
      }
      else
      {
 @@ -1580,6 +1585,9 @@
          StopFakeTimeline();
      }
  
 +#if defined(HELIX_FEATURE_POWER_SAVE)
 +    EndPowerSave();
 +#endif    
      ResetPlayer();
  
      return HXR_OK;
 @@ -3020,41 +3028,64 @@
  }
  
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -HX_RESULT CHXAudioPlayer::RetrieveRendererPowerSave() {
 -    if (m_pRendererPowerSave != NULL)
 +HX_RESULT CHXAudioPlayer::RetrievePowerSave() 
 +{
 +    HX_RESULT retVal = HXR_FAIL;
 +	
 +    if (m_pPowerSave)
      {
 -        return HXR_OK;
 +	    retVal = HXR_OK;
      }
 -
 -    if (m_pActiveClockSource != NULL &&
 -        (m_pActiveClockSource->QueryInterface(IID_IHXPowerSave, (void**) &m_pRendererPowerSave) == HXR_OK))
 +    else
      {
 -        return HXR_OK;
 +        if (m_pActiveClockSource != NULL )
 +        {    
 +	        if (m_pActiveClockSource->QueryInterface(IID_IHXPowerSave, (void**) &m_pPowerSave) == HXR_OK)
 +            {
 +                retVal = HXR_OK;
 +            }
 +        }
 +        else 
 +        {
 +            if(m_Owner)
 +            { //device powersave
 +	              IHXAudioDevice * pAudioDev = NULL;
 +	              m_Owner->QueryInterface(IID_IHXAudioDevice, (void**) &pAudioDev);
 +	            
 +                if(pAudioDev)
 +                {
 +                    if (pAudioDev->QueryInterface(IID_IHXPowerSave, (void**) &m_pPowerSave) == HXR_OK)
 +                    {
 +                        retVal = HXR_OK;
 +                    }
 +                    HX_RELEASE(pAudioDev);
 +                }
 +            }
 +        }
      }
 -
 -    m_pRendererPowerSave = NULL;
 -    return HXR_FAIL;
 +	
 +    return retVal;
  }
  
  /* IHXPowerSave methods */
  STDMETHODIMP CHXAudioPlayer::StartPowerSave (void)
  {
      HX_RESULT theErr = HXR_FAIL;
 +	
      if (IsInPowerSave())
      {
 -        return HXR_FAIL;
 +        theErr =  HXR_ALREADY_INITIALIZED;
      }
 -
 -    if (!CanStartPowerSave())
 -    {
 -        return HXR_FAIL;
 -    }
 -
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    else
      {
 -        theErr = m_pRendererPowerSave->StartPowerSave();
 +        if (CanStartPowerSave())
 +        {
 +            if (RetrievePowerSave() == HXR_OK)
 +            {
 +                theErr = m_pPowerSave->StartPowerSave();
 +            }     
 +        }
      }
 -
      if (theErr == HXR_OK)
      {
          m_bInPowerSave = TRUE;
 @@ -3066,21 +3097,20 @@
  STDMETHODIMP CHXAudioPlayer::EndPowerSave (void)
  {
      HX_RESULT theErr = HXR_FAIL;
 -    if (!IsInPowerSave())
 -    {
 -        return HXR_FAIL;
 -    }
 -
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +	
 +    if (IsInPowerSave())
      {
 -        theErr = m_pRendererPowerSave->EndPowerSave();
 +        if (RetrievePowerSave() == HXR_OK)
 +        {
 +	        theErr = m_pPowerSave->EndPowerSave();
 +        }
      }
 -
      if (theErr == HXR_OK)
      {
          m_bInPowerSave = FALSE;
 -        m_pRendererPowerSave = NULL;
      }
 +    HX_RELEASE(m_pPowerSave);
 +
      return theErr;
  }
  
 @@ -3091,33 +3121,106 @@
  
  STDMETHODIMP_(HXBOOL) CHXAudioPlayer::CanStartPowerSave (void)
  {
 -    if (m_bHasStreams)
 -    {
 -        return FALSE;
 -    }
 +    HXBOOL retVal = FALSE;
  
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    if (RetrievePowerSave() == HXR_OK)
      {
 -        return m_pRendererPowerSave->CanStartPowerSave();
 +        retVal = m_pPowerSave->CanStartPowerSave();
      }
  
 -    return FALSE;
 +    return retVal;
  }
  
  STDMETHODIMP_(ULONG32) CHXAudioPlayer::GetWakeUpInterval (void)
  {
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    if (RetrievePowerSave() == HXR_OK)
      {
 -        return m_pRendererPowerSave->GetWakeUpInterval();
 +        return m_pPowerSave->GetWakeUpInterval();
      }
 +    return 0;
 +}
 +
 +STDMETHODIMP CHXAudioPlayer::SetWakeUpInterval (ULONG32  ulWakeUpInterval)
 +{
 +    HX_RESULT retVal = HXR_FAIL;
 +	if (RetrievePowerSave() == HXR_OK)
 +    {
 +        retVal = m_pPowerSave->SetWakeUpInterval(ulWakeUpInterval);
 +    }
 +	
 +	return retVal;
 +}
 +#endif
 +void CHXAudioPlayer::ApplyTimeLineLimit()
 +{
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +    UINT32 ulLimitInMs = 0;
 +
 +    ulLimitInMs = m_ulLimitInMs - m_ulAPstartTime + m_ulADresumeTime;
 +    HXLOGL2(HXLOG_ADEV, "CHXAudioPlayer[%p]::ApplyTimeLineLimit ulLimitInMs:%lu ", this, ulLimitInMs);
 +    
 +    if(m_Owner)
 +    { // Set audio session timelinelimit
 +        IHXTimeLineLimit* pTimeLineLimit = NULL;
 +        m_Owner->QueryInterface(IID_IHXTimeLineLimit, (void**) & pTimeLineLimit);
 +        if(pTimeLineLimit != NULL)
 +        {
 +            UINT32 ulDevLimitInMs = pTimeLineLimit->SetLimit(ulLimitInMs );
 +            HX_RELEASE(pTimeLineLimit);
 +        }
 +    } // End of if(m_Owner)
 +#endif
 +}
 +
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +STDMETHODIMP 
 +CHXAudioPlayer::SetLimit (UINT32 ulLimitInMs )
 +{
 +    HXLOGL2(HXLOG_ADEV, "CHXAudioPlayer[%p]::SetLimit ulLimitInMs:%lu ", this, ulLimitInMs);
 +    //  Store the limit (Presentation duration)
 +    //  Should be applied on audio session during resume
 +    //  after adjusting the start time
 +    m_ulLimitInMs = ulLimitInMs;
 +
 +    return HXR_OK;
  }
  
 -STDMETHODIMP_(ULONG32) CHXAudioPlayer::SetWakeUpInterval (ULONG32 /*IN*/ ulWakeUpInterval)
 +STDMETHODIMP 
 +CHXAudioPlayer::GetLimit (UINT32 &ulLimitInMs )
  {
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    HX_RESULT retVal = HXR_FAIL;
 +
 +    HXLOGL2(HXLOG_ADEV, "CHXAudioPlayer[%p]::GetLimit m_ulLimitInMs:%lu m_ulAPstartTime:%lu", this, m_ulLimitInMs, m_ulAPstartTime);
 +
 +    if(m_ulLimitInMs > 0)
      {
 -        return m_pRendererPowerSave->SetWakeUpInterval(ulWakeUpInterval);
 +        ulLimitInMs = m_ulLimitInMs - m_ulAPstartTime + m_ulADresumeTime;
 +        retVal = HXR_OK;
      }
 +
 +    return retVal;
  }
  
 +STDMETHODIMP 
 +CHXAudioPlayer::ResetLimit()
 +{
 +    HX_RESULT retVal = HXR_OK;
 +
 +    m_ulLimitInMs = 0;
 +
 +    if(m_Owner)
 +    {
 +        IHXTimeLineLimit* pTimeLineLimit = NULL;
 +        m_Owner->QueryInterface(IID_IHXTimeLineLimit, (void**) & pTimeLineLimit);
 +        if(pTimeLineLimit != NULL)
 +        {
 +            retVal = pTimeLineLimit->ResetLimit();
 +            HX_RELEASE(pTimeLineLimit);
 +        }
 +    } // End of if(m_Owner)
 +
 +    HXLOGL3(HXLOG_CORE, "CHXAudioPlayer[%p]::ResetLimit retVal:%x ", this, retVal);
 +    return retVal;
 +
 +}
  #endif /*HELIX_FEATURE_POWER_SAVE*/

 
---------------------------------------------------------------------------------------------------------------

Index: hxaudses.h
===================================================================
RCS file: /cvsroot/client/audiosvc/pub/hxaudses.h,v
retrieving revision 1.33.8.1
diff -u -r1.33.8.1 hxaudses.h
--- hxaudses.h	18 Sep 2009 04:45:12 -0000	1.33.8.1
+++ hxaudses.h	31 Aug 2010 17:04:08 -0000
@@ -58,6 +58,10 @@
 #include 
 #endif
 #include "hxcore.h"
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxTimelineLimit.h"
+#include  "hxPowerSave.h"
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
 //  IHXTimelineWatcher defines.
 #  define TLW_PAUSE    1
 #  define TLW_RESUME   2
@@ -116,10 +120,6 @@
 struct IHXAudioHook;
 struct IHXInterruptState;
 
-#if defined(HELIX_FEATURE_POWER_SAVE)
-_INTERFACE IHXPowerSave;
-#endif // HELIX_FEATURE_POWER_SAVE
-
 typedef struct _HXAudioFormat HXAudioFormat;
 class CHXAudioPlayer;
 
@@ -151,7 +151,8 @@
     public IHXVolumeAdviseSink,
 #endif                          
 #ifdef HELIX_FEATURE_POWER_SAVE
-		      public IHXPowerSave,
+    public IHXPowerSave,
+    public IHXTimeLineLimit,
 #endif
     public IHXCallback,
     public IHXAudioResamplerManager,
@@ -328,7 +329,20 @@
                                          HXBOOL&     /*OUT*/    bChanged
                                          );
 
+protected:
+    void ApplyPushdownLimit(UINT16& ulPushdown);
+    void CreateAudDevInterfaces(IHXAudioDevice* pAudioDev);
+    void ReleaseAudDeviceInterfaces();
 #if defined(HELIX_FEATURE_POWER_SAVE)
+	HX_RESULT ComputePowerSaveModePushDown();
+	UINT32 UpdateLimit();
+    
+public:
+
+	/*Implement IHXTimeLineLimit*/
+	STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs );
+	STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs );
+	STDMETHOD(ResetLimit) (THIS);
     /* 
      * IHXPowerSave methods
      */
@@ -337,9 +351,9 @@
     STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
     STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
     STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
-    STDMETHOD_(ULONG32,SetWakeUpInterval)      ( THIS_ ULONG32 /*IN*/ ulWakeUpInterval );
+	STDMETHOD(SetWakeUpInterval  ) (THIS_ ULONG32 ulWakeUpInterval );
 #endif /*HELIX_FEATURE_POWER_SAVE*/
-
+public:
 
     /*
      *  IHXAudioDeviceManager2 methods
@@ -657,6 +671,11 @@
     HXBOOL                  m_bMute;                // the mute state
 #if defined(HELIX_FEATURE_POWER_SAVE)
     HXBOOL                  m_bInPowerSave;         // Player in power save mode
+    UINT32                  m_ulWakeUpInterval;
+    IHXPowerSave*           m_pPowerSave;  
+    IHXTimeLineLimit*       m_pTimeLineLimit;
+    UINT32                  m_ulLimitInMs; 
+    ULONG32                 m_ulPrePowerSavePushdown;
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
     /*

------------------------------------------------------------------------------------------------------------------

Index: hxaudses.cpp
===================================================================
RCS file: /cvsroot/client/audiosvc/hxaudses.cpp,v
retrieving revision 1.84.2.1.2.1
diff -u -r1.84.2.1.2.1 hxaudses.cpp
--- hxaudses.cpp	12 Jan 2010 08:37:46 -0000	1.84.2.1.2.1
+++ hxaudses.cpp	31 Aug 2010 17:19:08 -0000
@@ -233,6 +233,11 @@
     , m_bMute(FALSE)
 #if defined(HELIX_FEATURE_POWER_SAVE)
     , m_bInPowerSave(FALSE)
+    , m_ulWakeUpInterval(0)
+    , m_pPowerSave(NULL)
+    , m_pTimeLineLimit(NULL)
+    , m_ulLimitInMs (0)
+    , m_ulPrePowerSavePushdown(0)
 #endif /*HELIX_FEATURE_POWER_SAVE*/
     , m_dBufEndTime((double) 0.)
     , m_bDisableWrite(FALSE)
@@ -470,9 +475,22 @@
 #endif            
             { GET_IIDHANDLE(IID_IHXAudioPushdown2),      (IHXAudioPushdown2*)this       },
             { GET_IIDHANDLE(IID_IHXAudioDeviceHookManager), (IHXAudioDeviceHookManager*)this},
+#ifdef HELIX_FEATURE_POWER_SAVE
+            { GET_IIDHANDLE(IID_IHXTimeLineLimit), (IHXTimeLineLimit*)this },
+            { GET_IIDHANDLE(IID_IHXPowerSave), (IHXPowerSave*)this },
+#endif /*HELIX_FEATURE_POWER_SAVE*/
         };
 
-    return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
+    HX_RESULT retval = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
+
+#ifdef HELIX_FEATURE_POWER_SAVE
+    if (retval != HXR_OK && m_pCurrentAudioDev)
+    {
+        retval = m_pCurrentAudioDev->QueryInterface(riid, ppvObj);
+    }
+#endif
+
+    return retval; 
 }
 
 /////////////////////////////////////////////////////////////////////////
@@ -1243,6 +1261,7 @@
  */
 HX_RESULT CHXAudioSession::PlayAudio(UINT16 uNumBlocks)
 {
+    ApplyPushdownLimit(uNumBlocks);
     HXLOGL4(HXLOG_ADEV, "CHXAudioSession[%p]::PlayAudio(): %u blocks", this, uNumBlocks);
 
     HX_RESULT theErr = HXR_OK;
@@ -2073,6 +2092,7 @@
 
             m_pCurrentAudioDev = (IHXAudioDevice*) pAudioDev;
 
+            CreateAudDevInterfaces(pAudioDev);
             HXLOGL3(HXLOG_ADEV, "CHXAudioSession[%p]::CreateAudioDevice(): created [%p]", this, m_pCurrentAudioDev);
         }
         else
@@ -2097,6 +2117,7 @@
     _NotifyTimelineWatchers( TLW_CLOSE );
     HX_RELEASE(m_pCurrentAudioDev);
 
+    ReleaseAudDeviceInterfaces();
     m_bToBeReOpened = FALSE;
     if (m_pDeviceCallback && m_pDeviceCallback->PendingID())
     {
@@ -2633,11 +2654,13 @@
         m_pCurrentAudioDev->Close(TRUE);
         _NotifyTimelineWatchers( TLW_CLOSE );
         HX_RELEASE(m_pCurrentAudioDev);
+        ReleaseAudDeviceInterfaces();
     }
 
     m_pCurrentAudioDev = pAudioDevice;
     m_pCurrentAudioDev->AddRef();
 
+    CreateAudDevInterfaces(m_pCurrentAudioDev);
     m_pReplacedAudioDev = pAudioDevice;
     m_pReplacedAudioDev->AddRef();
 
@@ -2712,6 +2735,7 @@
         HX_RELEASE(m_pCurrentAudioDev);
     }
 
+    ReleaseAudDeviceInterfaces();
     HX_RELEASE(m_pReplacedAudioDev);
     m_bReplacedDev = FALSE;
 
@@ -4502,32 +4526,244 @@
     }
 }
 
+//
+//  CHXAudioSession::ApplyPushdownLimit
+//  Limits the pushdown value based on
+//  power save cfg
+//
+void CHXAudioSession::ApplyPushdownLimit(UINT16& ulPushdown)
+{
+    //  Reason to limit is to avoid the mixer from producing
+    //  dummy silence data at the end of the playback
+#ifdef HELIX_FEATURE_POWER_SAVE
+    if(m_bInPowerSave && m_ulLimitInMs > 0)
+    {
+        if( m_ulLimitInMs < ((m_ulBlocksWritten + ulPushdown) * m_dGranularity) )
+        {
+            // ulPushdown needs to update
+            ulPushdown = ((m_ulLimitInMs / m_dGranularity) - m_ulBlocksWritten);
+            // Adding a block to cover roundoff errors.
+            ulPushdown++;
+
+        }
+    } // End of if(m_bInPowerSave && m_ulLimitInMs > 0)
+#endif // End of #ifdef HELIX_FEATURE_POWER_SAVE
+}
+
+//
+//  CHXAudioSession::CreateAudDevInterfaces
+//  To create interfaces from audio device
+//
+void CHXAudioSession::CreateAudDevInterfaces(IHXAudioDevice* pAudioDev)
+{
+    ReleaseAudDeviceInterfaces();
+#ifdef HELIX_FEATURE_POWER_SAVE
+    if(pAudioDev != NULL)
+    {
+        pAudioDev->QueryInterface(IID_IHXPowerSave, (void**) &m_pPowerSave);
+        pAudioDev->QueryInterface(IID_IHXTimeLineLimit, (void**) &m_pTimeLineLimit);
+
+        if (m_pPowerSave==0 || m_pTimeLineLimit==0)
+        {
+            HXLOGL2(HXLOG_ADEV, "CHXAudioSession::CreateAudDevInterfaces:query m_pPowerSave or m_pTimeLineLimit return 0");
+        }
+
+    }
+#endif
+}
+
+//
+//  CHXAudioSession::ReleaseAudDeviceInterfaces
+//  releases interfaces created from audio device
+//
+void CHXAudioSession::ReleaseAudDeviceInterfaces()
+{
+#ifdef HELIX_FEATURE_POWER_SAVE
+    HX_RELEASE(m_pPowerSave);
+    HX_RELEASE(m_pTimeLineLimit);
+#endif
+}
+
+
 #if defined(HELIX_FEATURE_POWER_SAVE)
-/* IHXPowerSave methods */
-STDMETHODIMP_(HX_RESULT) CHXAudioSession::StartPowerSave (void)
+//
+//  CHXAudioSession::UpdateLimit
+//  Queries the limit from all players
+//  and uses the min for device and max for
+//  pushdown limit
+//
+UINT32 CHXAudioSession::UpdateLimit()
 {
-    HX_RESULT theErr = HXR_FAIL;
-    if (IsInPowerSave())
+    UINT32 ulLowestLimitInMs = MAX_UINT32;
+    UINT32 ulHighestLimitInMs = 0;
+    HX_RESULT rv = HXR_OK;
+
+    HXLOGL3(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): m_pPlayerList = %p", this, m_pPlayerList);
+    if(m_pPlayerList && m_pPlayerList->GetCount() > 0)
     {
-        return HXR_FAIL;
+
+        CHXAudioPlayer* pPlayer = NULL;
+        CHXSimpleList::Iterator lIter;
+        for (lIter = m_pPlayerList->Begin(); lIter != m_pPlayerList->End(); ++lIter)
+        {
+            IHXTimeLineLimit* pTimeLimit = NULL;
+            pPlayer = (CHXAudioPlayer*) (*lIter);
+            pPlayer->QueryInterface(IID_IHXTimeLineLimit, (void**) &pTimeLimit);
+            if(pTimeLimit)
+            {
+                UINT32 ulLimit = 0;
+                rv = pTimeLimit->GetLimit(ulLimit);
+                HXLOGL2(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): pTimeLimit:%p ulLimit:%lu", this, pTimeLimit, ulLimit);
+                HX_RELEASE(pTimeLimit);
+                if( (rv == HXR_NO_DATA) || (ulLimit == 0) )
+                {
+                    // Player is not interested in applying limit
+                    // break out
+                    ulLowestLimitInMs = 0;
+                    ulHighestLimitInMs = 0;
+                    break;
+                }
+                else
+                {
+                    if(ulLimit < ulLowestLimitInMs)
+                    {
+                        ulLowestLimitInMs = ulLimit;
+                    }
+
+                    if(ulLimit > ulHighestLimitInMs)
+                    {
+                        ulHighestLimitInMs = ulLimit;
+                    }
+                }
+            }
+            else
+            {
+                // One of the player is not interested in applying limit
+                // break out
+                ulLowestLimitInMs = 0;
+                ulHighestLimitInMs = 0;
+                HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): IHXTimeLineLimit NOT SUPPOPRTED", this);
+                break;
+            }
+
+        } // End of for (lIter = m_pPlayerList->Begin(); lIter != m_pPlayerList->End(); ++lIter)
+
+
+    } // End of if(m_pPlayerList && m_pPlayerList->GetCount() > 0)
+
+    HXLOGL2(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): Hi:%lu Lo:%lu", this, ulHighestLimitInMs, ulLowestLimitInMs);
+    if( (ulHighestLimitInMs != 0) && (ulLowestLimitInMs != 0) )
+    {
+        // highest value is used for max pushdown calculation
+        // Typically this is the duration of the playback
+        // start time is already adjusted on this limit
+        m_ulLimitInMs = ulHighestLimitInMs;
+
+        //set dev from audply
+        if(m_pTimeLineLimit != NULL)
+        {
+            // Lowest is set on the device
+            m_pTimeLineLimit->SetLimit(ulLowestLimitInMs);
+        }
+    } // End of if( (ulHighestLimitInMs != 0) && (ulLowestLimitInMs != 0) )
+    return ulLowestLimitInMs;
+}
+
+HX_RESULT CHXAudioSession::ComputePowerSaveModePushDown()
+{
+    HX_RESULT retVal = HXR_OK;
+    if(m_ulWakeUpInterval != 0)
+    {
+        retVal = SetAudioPushdown(m_ulWakeUpInterval);
     }
+	return retVal;
+}
+STDMETHODIMP CHXAudioSession::SetLimit (UINT32 ulLimitInMs )
+{
+    UINT32 retVal = 0;
+    m_pMutex->Lock();
 
-    if (!CanStartPowerSave())
+    //  ulLimitInMs is ignored
+    //  limit values are queried from all audio players
+    //  this call is used for getting limits from
+    //  all audio players
+
+    if(m_bInPowerSave)
     {
-        return HXR_FAIL;
+        retVal = UpdateLimit();
+        HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::SetLimit(): m_ulLimitInMs[%lu] ", this, m_ulLimitInMs);
     }
 
+    m_pMutex->Unlock();
 
-    if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+    return retVal;
+}
+
+STDMETHODIMP CHXAudioSession::GetLimit (UINT32 &ulLimitInMs )
+{
+    HX_RESULT retVal = HXR_FAIL;
+
+    m_pMutex->Lock();
+
+    if(m_ulLimitInMs != 0)
     {
-        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
-        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        theErr = pPlayer->StartPowerSave();
+        ulLimitInMs = m_ulLimitInMs;
+        retVal = HXR_OK;
     }
 
-    if (theErr == HXR_OK)
+    HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::GetLimit(): retVal = %x ulLimitInMs[%lu] ", this, ulLimitInMs);
+
+    m_pMutex->Unlock();
+
+    return retVal;
+}
+
+STDMETHODIMP CHXAudioSession::ResetLimit ()
+{
+	m_pMutex->Lock();
+
+	m_ulLimitInMs = 0;
+
+	if(m_pTimeLineLimit)
+	{
+		m_pTimeLineLimit->ResetLimit();
+	}
+
+	HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::ResetLimit() ", this);
+
+	m_pMutex->Unlock();
+
+	return HXR_OK;
+}
+/* IHXPowerSave methods */
+STDMETHODIMP_(HX_RESULT) CHXAudioSession::StartPowerSave (void)
+{
+    HXLOGL2(HXLOG_ADEV, "CHXAudioSession[%p]::StartPowerSave() ");
+    HX_RESULT theErr = HXR_FAIL;
+	
+    if (IsInPowerSave())
     {
-        m_bInPowerSave = TRUE;
+        theErr =  HXR_ALREADY_INITIALIZED;
+    }
+    else
+    {
+        if (CanStartPowerSave())
+        {
+            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+            CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+            if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+            {
+                theErr = pPlayer->StartPowerSave();
+
+                if (theErr == HXR_OK)
+                {
+                    m_bInPowerSave = TRUE;
+                    m_ulWakeUpInterval = pPlayer->GetWakeUpInterval();
+                    m_ulPrePowerSavePushdown = m_ulTargetPushdown;
+                    ComputePowerSaveModePushDown();
+                }
+            }
+        }
     }
 
     return theErr;
@@ -4535,18 +4771,22 @@
 
 STDMETHODIMP_(HX_RESULT) CHXAudioSession::EndPowerSave (void)
 {
+    HXLOGL2(HXLOG_ADEV, "CHXAudioSession[%p]::EndPowerSave() ");
     HX_RESULT theErr = HXR_FAIL;
-    if (!IsInPowerSave())
+	
+    if (IsInPowerSave())
     {
-        return HXR_FAIL;
+        if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+        {
+            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+            CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+            theErr = pPlayer->EndPowerSave();
+            UINT32 ulMinimumPushdown = (m_ulMinimumStartupPushdownGetCount() == 1)
-    {
-        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
-        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        theErr = pPlayer->EndPowerSave();
-    }
 
     if (theErr == HXR_OK)
     {
@@ -4563,41 +4803,45 @@
 
 STDMETHODIMP_(HXBOOL) CHXAudioSession::CanStartPowerSave (void)
 {
-    if (m_bHasStreams)
-    {
-        return FALSE;
-    }
-
-    if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+    HXBOOL retVal = FALSE;
+	
+    if (m_pPlayerList )
     {
-        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
-        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        return pPlayer->CanStartPowerSave();
+        if (m_pPlayerList->GetCount() == 1)
+        {
+            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+            CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+            retVal = pPlayer->CanStartPowerSave();
+        }
     }
 
-    return FALSE;
+    return retVal;
 }
 
-STDMETHODIMP_(ULONG32) CHXAudioSession::GetWakeUpInterval (void)
+STDMETHODIMP_(ULONG32) CHXAudioSession::GetWakeUpInterval ()
 {
+    ULONG32 ulWakeUpInterval = 0;
+	
     if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
     {
         CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
         CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        return pPlayer->GetWakeUpInterval();
+        ulWakeUpInterval = pPlayer->GetWakeUpInterval();
     }
-    return 0;
+    HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::GetWakeUpInterval(): ulWakeUpInterval = %lu ", ulWakeUpInterval);
+    return ulWakeUpInterval;
 }
 
-STDMETHODIMP_(ULONG32) CHXAudioSession::SetWakeUpInterval (ULONG32 /*IN*/ ulWakeUpInterval)
+STDMETHODIMP CHXAudioSession::SetWakeUpInterval(ULONG32 ulWakeUpInterval )
 {
+    HX_RESULT retVal = HXR_FAIL;
     if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
     {
         CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
         CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        return pPlayer->SetWakeUpInterval(ulWakeUpInterval);
+        retVal = pPlayer->SetWakeUpInterval(ulWakeUpInterval);
     }
-    return 0;
+    return retVal;
 }
 
 #endif /*HELIX_FEATURE_POWER_SAVE*/

 ---------------------------------------------------------------------------------------------------------------------
 
 Index: hxcleng.h
 ===================================================================
 RCS file: /cvsroot/client/core/pub/hxcleng.h,v
 retrieving revision 1.50.2.1
 diff -u -r1.50.2.1 hxcleng.h
 --- hxcleng.h	18 Sep 2009 04:46:03 -0000	1.50.2.1
 +++ hxcleng.h	31 Aug 2010 18:18:48 -0000
 @@ -76,6 +76,9 @@
  #define _MEDIUM_BLOCK 1
  #endif
  
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +#include  "hxPowerSave.h"
 +#endif /*HELIX_FEATURE_POWER_SAVE*/
  class	HXCommonClassFactory;
  class	HXScheduler;
  class   HXOptimizedSchedulerBase;
 @@ -137,10 +140,6 @@
  #endif
  #endif //HELIX_FEATURE_NETSERVICES
  
 -#if defined(HELIX_FEATURE_POWER_SAVE)
 -_INTERFACE IHXPowerSave;
 -#endif // HELIX_FEATURE_POWER_SAVE
 -
  #if defined(HELIX_FEATURE_SYSTEMREQUIRED)
  class HXSystemRequired : public IHXSystemRequired
  {
 @@ -624,7 +623,7 @@
      STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
      STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
      STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
 -    STDMETHOD_(ULONG32,SetWakeUpInterval)      ( THIS_ ULONG32 /*IN*/ ulWakeUpInterval );
 +    STDMETHOD(SetWakeUpInterval)               ( THIS_ ULONG32 ulWakeUpInterval );
  #endif /*HELIX_FEATURE_POWER_SAVE*/
  
  
 @@ -668,8 +667,9 @@
      HXTimeval*                    m_pCurrentTime;
  #endif /*HELIX_FEATURE_SYSTEM_EXTERNAL_TIMER*/
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -    HXBOOL			m_bInPowerSave;
 -    ULONG32			m_ulWakeUpInterval;
 +    HXBOOL             m_bInPowerSave;
 +    HXBOOL             m_bPowerSaveModeAllowed;
 +    ULONG32            m_ulWakeUpInterval;
  #endif /*HELIX_FEATURE_POWER_SAVE*/
  
  };
 -------------------------------------------------------------------------------------------------------------
 
 Index: hxcleng.cpp
 ===================================================================
 RCS file: /cvsroot/client/core/hxcleng.cpp,v
 retrieving revision 1.136.8.1.2.1
 diff -u -r1.136.8.1.2.1 hxcleng.cpp
 --- hxcleng.cpp	28 Apr 2010 20:52:56 -0000	1.136.8.1.2.1
 +++ hxcleng.cpp	31 Aug 2010 18:27:17 -0000
 @@ -388,6 +388,7 @@
  
  ,m_pContext(NULL)
  #if defined(HELIX_FEATURE_POWER_SAVE)
 +,m_bPowerSaveModeAllowed(FALSE)
  ,m_bInPowerSave(FALSE)
  ,m_ulWakeUpInterval(DEFAULT_WAKEUP_INTERVAL)
  #endif /*HELIX_FEATURE_POWER_SAVE*/
 @@ -858,7 +859,12 @@
          ReadPrefBOOL(m_pPreferences, "UseCoreThread", m_bUseCoreThread);  
      }
  #endif /*_WIN32*/
 +#ifdef HELIX_FEATURE_POWER_SAVE
  
 +	ReadPrefBOOL(m_pPreferences, "EnablePowerSaveMode", m_bPowerSaveModeAllowed);
 +	HXLOGL1( HXLOG_CORE, "Preferences values are: m_bPowerSaveModeAllowed %d ", m_bPowerSaveModeAllowed );
 +
 +#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
      InitializeThreadedObjects();
  
  #if defined(HELIX_FEATURE_AUDIO)
 @@ -1024,7 +1030,9 @@
          { GET_IIDHANDLE(IID_IHXAutoBWCalibrationAdviseSink), (IHXAutoBWCalibrationAdviseSink*)this },
  	{ GET_IIDHANDLE(IID_IHXContextUser), (IHXContextUser*)this },
  // #ifdef..
 +#ifdef HELIX_FEATURE_POWER_SAVE
  	{ GET_IIDHANDLE(IID_IHXPowerSave), (IHXPowerSave*)this }
 +#endif /*HELIX_FEATURE_POWER_SAVE*/
      };
      HX_RESULT retval = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
      if (retval == HXR_OK)
 @@ -2629,6 +2637,13 @@
   const char* pMoreInfoURL
   )
  {
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +    if (unSeverity != HXLOG_DEBUG   &&
 +        ulHXCode  != HXR_OK)
 +    {
 +        EndPowerSave();
 +    }
 +#endif
      if (m_PlayerList.GetCount())
      {
          HXPlayer* pHXPlayer = (HXPlayer*)m_PlayerList.GetTail();
 @@ -3036,25 +3051,32 @@
  #if defined(HELIX_FEATURE_POWER_SAVE)
  STDMETHODIMP_(HX_RESULT) HXClientEngine::StartPowerSave(void)
  {
 -    HX_RESULT theErr = HXR_OK;
 +    HX_RESULT theErr = HXR_FAIL;
 +    HXLOGL2( HXLOG_CORE, "HXClientEngine[%p]::StartPowerSave m_bPowerSaveModeAllowed:%d m_bInPowerSave:%d", this, m_bPowerSaveModeAllowed, m_bInPowerSave);
  
 -    if (!CanStartPowerSave())
 +    if (m_pCoreMutex)
      {
 -        return HXR_FAIL;
 +        m_pCoreMutex->Lock();
      }
 -
 -    if (m_pAudioSession)
 +    if (CanStartPowerSave())
      {
 -        m_ulWakeUpInterval = m_pAudioSession->SetWakeUpInterval(m_ulWakeUpInterval);
 -        theErr = m_pAudioSession->StartPowerSave();
 -
 -        /* Add the interval to HXPlayer */
 -        HX_ASSERT(GetPlayerCount() == 1);
 -
 -        HXPlayer* pPlayer = m_PlayerList.GetHead();
 -        if (pPlayer != NULL)
 +        if (m_pAudioSession)
          {
 -            pPlayer->AdjustWakeUpInterval(m_ulWakeUpInterval);
 +            m_pAudioSession->SetWakeUpInterval(m_ulWakeUpInterval);
 +            m_ulWakeUpInterval = m_pAudioSession->GetWakeUpInterval();
 +            theErr = m_pAudioSession->StartPowerSave();
 +
 +            /* Add the interval to HXPlayer */
 +            HX_ASSERT(GetPlayerCount() == 1);
 +            LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
 +            if (lPosition != NULL)
 +            {
 +                HXPlayer* pPlayer = (HXPlayer*) m_PlayerList.GetAt(lPosition);
 +                if (pPlayer != NULL)
 +                {
 +                    pPlayer->AdjustWakeUpInterval(m_ulWakeUpInterval);
 +                }
 +            }
          }
      }
  
 @@ -3067,27 +3089,39 @@
          EndPowerSave();
      }
  
 +    if (m_pCoreMutex)
 +    {
 +        m_pCoreMutex->Unlock();
 +    }
      return theErr;
  }
  
  STDMETHODIMP_(HX_RESULT) HXClientEngine::EndPowerSave(void)
  {
 -    HX_RESULT theErr = HXR_OK;
 -
 -    if (!IsInPowerSave())
 +   HXLOGL2( HXLOG_CORE, "HXClientEngine[%p]::EndPowerSave m_bPowerSaveModeAllowed:%d m_bInPowerSave:%d", this, m_bPowerSaveModeAllowed, m_bInPowerSave);
 +    HX_RESULT theErr = HXR_FAIL;
 +    if (m_pCoreMutex)
      {
 -        return HXR_FAIL;
 +        m_pCoreMutex->Lock();
      }
  
 -    if (m_pAudioSession)
 +    if (IsInPowerSave())
      {
 -        theErr = m_pAudioSession->EndPowerSave();
 +        if (m_pAudioSession)
 +        {
 +            theErr = m_pAudioSession->EndPowerSave();
 +        }
      }
  
      if (theErr == HXR_OK)
      {
          m_bInPowerSave = FALSE;
      }
 +	
 +    if (m_pCoreMutex)
 +    {
 +        m_pCoreMutex->Unlock();
 +    }
  
      return theErr;
  }
 @@ -3099,39 +3133,38 @@
  
  STDMETHODIMP_(HXBOOL) HXClientEngine::CanStartPowerSave(void)
  {
 -    if ((GetPlayerCount() > 1) || m_bInPowerSave)
 +    HXBOOL retVal = FALSE;
 +    if ((GetPlayerCount() == 1)&& !m_bInPowerSave && m_bPowerSaveModeAllowed)
      {
 -        return FALSE;
 -    }
 -
 -    LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
 -    if (lPosition != NULL)
 -    {
 -        HXPlayer* pPlayer = (HXPlayer*) m_PlayerList.GetAt(lPosition);
 -        if (pPlayer != NULL && !pPlayer->IsLocalSource())
 +        LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
 +        if (lPosition != NULL)
          {
 -            return FALSE;
 +            HXPlayer* pPlayer = (HXPlayer*) m_PlayerList.GetAt(lPosition);
 +            if (pPlayer && pPlayer->IsPowerSaveCapable()) 
 +            {
 +                if (m_pAudioSession)
 +                {
 +                    retVal = m_pAudioSession->CanStartPowerSave();
 +                }
 +            }     
          }
      }
  
 -    if (m_pAudioSession)
 -    {
 -        return m_pAudioSession->CanStartPowerSave();
 -    }
  
 -    return FALSE;
 +    return retVal;
  }
  
  STDMETHODIMP_(ULONG32) HXClientEngine::GetWakeUpInterval(void)
  {
 +    HXLOGL2( HXLOG_CORE, "HXClientEngine[%p]::GetWakeUpInterval  m_ulWakeUpInterval: %lu ",m_ulWakeUpInterval);
      return m_ulWakeUpInterval;
  }
  
 -STDMETHODIMP_(ULONG32) HXClientEngine::SetWakeUpInterval( ULONG32 /*IN*/ ulWakeUpInterval)
 +STDMETHODIMP HXClientEngine::SetWakeUpInterval( ULONG32  ulWakeUpInterval)
  {
      m_ulWakeUpInterval = ulWakeUpInterval;
  
 -    return m_ulWakeUpInterval;
 +    return HXR_OK;
  }
  
  #endif /*HELIX_FEATURE_POWER_SAVE*/
 

--------------------------------------------------------------------------------------------------------------------

Index: hxplay.h
===================================================================
RCS file: /cvsroot/client/core/pub/hxplay.h,v
retrieving revision 1.69.8.1
diff -u -r1.69.8.1 hxplay.h
--- hxplay.h	18 Sep 2009 04:46:03 -0000	1.69.8.1
+++ hxplay.h	31 Aug 2010 18:31:25 -0000
@@ -218,7 +218,9 @@
 /* Lowest allowable time sync granularity */
 #define MINIMUM_TIMESYNC_GRANULARITY	20
 
+
 #define DEFAULT_WAKEUP_INTERVAL		100
+
 #ifndef _WIN16
 //#if defined(HELIX_FEATURE_AUTHENTICATION)
 typedef WRAPPED_POINTER(IUnknown) Wrapped_IUnknown;
@@ -1649,13 +1651,15 @@
     {
         m_ulPlayerWakeUpInterval = ulWakeUpInterval;
     }
+    HXBOOL IsPowerSaveCapable();
+    HX_RESULT UpdatePowerSaveLimit();
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
     /* Examine all sources in the player.  If any source is a network 
        source (HXNetSource), it will fail.  If any source is a file 
        source (HXFileSource) and either a file or file format object 
        report NETWORKACCESS, it will fail. */
-    HXBOOL IsLocalSource();
+
 
     ////////////////////////////////////////////////////////////////////
     //
@@ -2252,6 +2256,7 @@
     IHXRecordService*	        m_pRecordService;
     HXBOOL                      m_bRecordServiceEnabled;
 
+    IHXScheduler3*              m_pScheduler3;
 #if defined(HELIX_FEATURE_POWER_SAVE)
     ULONG32                     m_ulPlayerWakeUpInterval;
 #endif

------------------------------------------------------------------------------------------------------------
Index: hxplay.cpp
===================================================================
RCS file: /cvsroot/client/core/hxplay.cpp,v
retrieving revision 1.200.8.1.2.1
diff -u -r1.200.8.1.2.1 hxplay.cpp
--- hxplay.cpp	9 Nov 2009 09:22:52 -0000	1.200.8.1.2.1
+++ hxplay.cpp	31 Aug 2010 18:36:40 -0000
@@ -430,6 +430,7 @@
     ,m_pSharedWallClocks(NULL)
     ,m_pRecordService(NULL)
     ,m_bRecordServiceEnabled(FALSE)
+    , m_pScheduler3(NULL)
 #if defined(HELIX_FEATURE_POWER_SAVE)
     ,m_ulPlayerWakeUpInterval(0)
 #endif //HELIX_FEATURE_POWER_SAVE
@@ -1673,6 +1674,11 @@
     CreateInstanceCCF(CLSID_IHXUpgradeCollection, (void**)&m_pUpgradeCollection, (IUnknown*)(IHXClientEngine*)m_pEngine);  
 #endif /* HELIX_FEATURE_AUTOUPGRADE */
 
+    HX_RELEASE(m_pScheduler3);
+    m_pScheduler->QueryInterface(IID_IHXScheduler3, (void**)&m_pScheduler3);
+
+    HXLOGL4( HXLOG_CORE, "HXPlayer::m_pScheduler3[%p]", m_pScheduler3);
+
     return theErr;
 }
 
@@ -6605,6 +6611,8 @@
     HX_RELEASE (m_pRegistry);
 #endif /* HELIX_FEATURE_REGISTRY */
 
+    HX_RELEASE(m_pScheduler3);
+
     HX_RELEASE (m_pEngine);
     HX_RELEASE (m_pClient);
     HX_RELEASE (m_pScheduler);
@@ -9590,7 +9598,10 @@
     {
         m_pAdviseSink->OnPosLength(m_ulCurrentPlayTime, m_ulPresentationDuration);
     }
+#ifdef HELIX_FEATURE_POWER_SAVE
 
+    UpdatePowerSaveLimit();
+#endif /*HELIX_FEATURE_POWER_SAVE*/
     return;
 }
 
@@ -11402,14 +11413,13 @@
 #endif  // _MACINTOSH
 
 #if defined(HELIX_FEATURE_POWER_SAVE) && defined(HELIX_FEATURE_AUDIO)
-    if (m_pAudioPlayer && m_pAudioPlayer->IsInPowerSave())
+    if (m_pAudioPlayer && m_pScheduler3 
+            && !m_pScheduler3->IsPaused()&& m_pAudioPlayer->IsInPowerSave())
     {
         // the actually interval from device may differ slightly from set from user (due to some alignment).
         // todo, do we need get this interval each time? 
         // is there possiblity that the interval modified from render/device unpredictably?
-        m_ulPlayerWakeUpInterval = m_pAudioPlayer->GetWakeUpInterval();
-        if (ulRet < m_ulPlayerWakeUpInterval)
-            ulRet = m_ulPlayerWakeUpInterval;//FIXME-Y
+        ulRet += m_ulPlayerWakeUpInterval;
     }
 #endif // (HELIX_FEATURE_POWER_SAVE) && (HELIX_FEATURE_AUDIO)
 
@@ -13958,22 +13968,33 @@
     }
 }
 
-HXBOOL HXPlayer::IsLocalSource()
+#ifdef HELIX_FEATURE_POWER_SAVE
+HX_RESULT HXPlayer::UpdatePowerSaveLimit()
 {
-    CHXMapPtrToPtr::Iterator iter = m_pSourceMap->Begin();
-    while(iter != m_pSourceMap->End())
+    HX_RESULT retVal = HXR_FAIL;
+    if(m_pAudioPlayer)
     {
-        SourceInfo* pSourceInfo = (SourceInfo*)(*iter);
-        HX_ASSERT (pSourceInfo != NULL);
+        HXLOGL1( HXLOG_CORE, "HXPlayer[%p]::UpdatePowerSaveLimit Limit:%lu", this, m_ulPresentationDuration);
+        retVal = m_pAudioPlayer->SetLimit (m_ulPresentationDuration);
+    }
+    return retVal;
+}
+
+HXBOOL HXPlayer::IsPowerSaveCapable()
+{
+    HXBOOL bPowerSaveCapable = FALSE;
+    if((m_pSourceMap != NULL) &&
+        (m_pSourceMap->GetCount() == 1) )
+    {
+        CHXMapPtrToPtr::Iterator    ndxSource;
+        ndxSource = m_pSourceMap->Begin();
+        SourceInfo* pSourceInfo = (SourceInfo*) (*ndxSource);
         HXSource* pSource = pSourceInfo->m_pSource;
-        if (pSource != NULL)
+        if(pSource && !(pSource->UsesNetworkAccess()))
         {
-            if (((HXSource*)pSource)->UsesNetworkAccess())
-            {
-                return FALSE;
-            }
+            bPowerSaveCapable = TRUE;
         }
-        ++iter;
-    }
-    return TRUE;
+    } 
+    return bPowerSaveCapable;
 }
+#endif /*HELIX_FEATURE_POWER_SAVE*/

--------------------------------------------------------------------------------------------------------

Index: chxmedpltfmsched.h
===================================================================
RCS file: /cvsroot/client/medpltfm/pub/chxmedpltfmsched.h,v
retrieving revision 1.7
diff -u -r1.7 chxmedpltfmsched.h
--- chxmedpltfmsched.h	6 Jul 2007 21:58:21 -0000	1.7
+++ chxmedpltfmsched.h	31 Aug 2010 18:47:47 -0000
@@ -57,8 +57,9 @@
 class CHXMediaPlatformKicker;
 
 class CHXMediaPlatformScheduler : public CUnknownIMP
-				, public IHXScheduler
-				, public IHXScheduler2
+                , public IHXScheduler
+                , public IHXScheduler2
+                , public IHXScheduler3
 {
 protected:
     UINT32			m_ulThreadID;
@@ -114,6 +115,9 @@
 						    ULONG32 ulTimeout);
     STDMETHOD_(ULONG32, GetThreadID)		    (THIS);
     STDMETHOD_(HXBOOL, AreImmediatesPending)	    (THIS);
+    STDMETHOD(PauseScheduler)   (THIS_);    
+    STDMETHOD(ResumeScheduler)  (THIS_);
+    STDMETHOD_(HXBOOL, IsPaused)  (THIS_);
 
     HX_RESULT	Init(IUnknown* pContext);
     HX_RESULT	AttachKicker(CHXMediaPlatformKicker* pKicker);

------------------------------------------------------------------------------------------------------------

Index: chxmedpltfmsched.cpp
===================================================================
RCS file: /cvsroot/client/medpltfm/chxmedpltfmsched.cpp,v
retrieving revision 1.8
diff -u -r1.8 chxmedpltfmsched.cpp
--- chxmedpltfmsched.cpp	6 Jul 2007 21:58:19 -0000	1.8
+++ chxmedpltfmsched.cpp	12 Aug 2010 22:15:54 -0000
@@ -60,6 +60,7 @@
 BEGIN_INTERFACE_LIST_NOCREATE(CHXMediaPlatformScheduler)
     INTERFACE_LIST_ENTRY_SIMPLE(IHXScheduler)
     INTERFACE_LIST_ENTRY_SIMPLE(IHXScheduler2)
+    INTERFACE_LIST_ENTRY_SIMPLE(IHXScheduler3)
     INTERFACE_LIST_ENTRY_DELEGATE(IID_IHXMutex, _InternalQIMutex)
 END_INTERFACE_LIST
 
@@ -213,6 +214,24 @@
     return m_pScheduler ? m_pScheduler->AreImmediatesPending() : FALSE; 
 }
 
+STDMETHODIMP
+CHXMediaPlatformScheduler::PauseScheduler()
+{
+    return m_pScheduler ? m_pScheduler->PauseScheduler() : HXR_FAILED;
+}
+
+STDMETHODIMP
+CHXMediaPlatformScheduler::ResumeScheduler()
+{
+    return m_pScheduler ? m_pScheduler->ResumeScheduler() : HXR_FAILED;
+}
+
+STDMETHODIMP_(HXBOOL)
+CHXMediaPlatformScheduler::IsPaused(void)
+{
+    return m_pScheduler ? m_pScheduler->IsPaused() : FALSE; 
+}
+
 HX_RESULT
 CHXMediaPlatformScheduler::_InternalQIMutex(REFIID riid, void** ppvObj)
 {

------------------------------------------------------------------------------------------------------------
Index: chxmedpltfm.cpp
===================================================================
RCS file: /cvsroot/client/medpltfm/chxmedpltfm.cpp,v
retrieving revision 1.78.4.3
diff -u -r1.78.4.3 chxmedpltfm.cpp
--- chxmedpltfm.cpp	7 Jul 2010 23:21:52 -0000	1.78.4.3
+++ chxmedpltfm.cpp	9 Aug 2010 16:27:22 -0000
@@ -1141,8 +1141,9 @@
         {
             rc = m_pMutex ? m_pMutex->QueryInterface(riid, ppvObj) : HXR_NOTIMPL;
         }
-        else if ((IsEqualIID(riid, IID_IHXScheduler) ||
-                  IsEqualIID(riid, IID_IHXScheduler2)))
+        else if (IsEqualIID(riid, IID_IHXScheduler) ||
+                  IsEqualIID(riid, IID_IHXScheduler2)||
+                  IsEqualIID(riid, IID_IHXScheduler3))
         {
             rc = m_pScheduler ? m_pScheduler->QueryInterface(riid, ppvObj) : HXR_NOTIMPL;
         }


---------------------------------------------------------------------------------------------------------------

Index: R1_Mobile_4_0_Factory.cfg
===================================================================
RCS file: /cvsroot/clientapps/symbiancommon/config/R1_Mobile_4_0_Factory.cfg,v
retrieving revision 1.57.4.5
diff -u -r1.57.4.5 R1_Mobile_4_0_Factory.cfg
--- R1_Mobile_4_0_Factory.cfg	17 Jun 2010 12:37:53 -0000	1.57.4.5
+++ R1_Mobile_4_0_Factory.cfg	26 Aug 2010 15:59:46 -0000
@@ -62,7 +62,7 @@
 LinkChar-MTD=2000
 BaseAdaptationTargetTime=5000
 UseCMMFHWDeviceAudioCodec=0
-UseWMACMMFHWDeviceAudioCodec=0
+UseWMACMMFHWDeviceAudioCodec=1
 MetaDataKeys=Title,Copyright,Author,Abstract,Genre,Performer,Album,Tracknumber,WM/AlbumTitle,WM/Year,WM/Text,WM/TrackNumber,WM/Genre,WM/Composer,WM/OriginalArtist,WM/Picture,WM/AudioFileURL,WM/Provider
 #Partial PlayBack values
 DisablePartialPlayback=0
@@ -155,3 +155,6 @@
 UDPFirewallKnock=1
 # Maximum preroll supported for local playback
 MaxVideoPreroll=4000
+
+# For Power Save feature with AudioController
+EnablePowerSaveMode=1

------------------------------------------------------------------------------------------------------------------

Index: hxmmfstatectrl.h
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/hxmmfstatectrl.h,v
retrieving revision 1.19.12.8
diff -u -r1.19.12.8 hxmmfstatectrl.h
--- hxmmfstatectrl.h	12 May 2010 19:27:56 -0000	1.19.12.8
+++ hxmmfstatectrl.h	24 Aug 2010 20:12:53 -0000
@@ -74,6 +74,9 @@
 #define HXR_SEND_BUFFER_START                     0x1
 #define HXR_SEND_BUFFER_COMPLETE                  0x2
 #define HXR_SEND_BUFFER_UNKNOWN                   0x4
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxPowerSave.h"
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
 
 #define POST_SEEK_TIMER_VALUE  5000*1000  //5 seconds
 
@@ -182,6 +185,8 @@
     virtual HX_RESULT StepFrames(TInt aStep);
 #endif
 
+    void StartPowerSave();
+    void EndPowerSave();
   protected:
     HXMMFPlayCtrl*        m_pPlayerControl;
     HXMMFState*           m_pCurrentState;
@@ -261,6 +266,11 @@
     UINT8     m_bufferStatus;
     HXBOOL    m_bVideoController;
     TThreadId m_clientTid;
+#ifdef HELIX_FEATURE_POWER_SAVE
+private:
+	IHXPowerSave* m_pPowerSave;
+	IHXScheduler3* m_pScheduler3;
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 };
 
 #endif _HX_MMF_STATE_CTRL_H_

------------------------------------------------------------------------------------------------------------

Index: hxmmfstatectrl.cpp
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/hxmmfstatectrl.cpp,v
retrieving revision 1.32.12.13
diff -u -r1.32.12.13 hxmmfstatectrl.cpp
--- hxmmfstatectrl.cpp	12 Jul 2010 16:43:48 -0000	1.32.12.13
+++ hxmmfstatectrl.cpp	31 Aug 2010 18:56:21 -0000
@@ -307,7 +307,16 @@
 ULONG32
 HXMMFStateCtrl::GetPosition()
 {
-    return(m_posLength);
+#ifdef HELIX_FEATURE_POWER_SAVE
+	if(m_pScheduler3
+	&& m_pScheduler3->IsPaused()
+	&& m_pPlayerControl
+	&& m_pPlayerControl->m_pHXPlayer)
+	{
+		m_posLength = m_pPlayerControl->m_pHXPlayer->GetCurrentPlayTime();
+	}
+#endif /*HELIX_FEATURE_POWER_SAVE*/
+	return m_posLength;
 }
 
 ULONG32
@@ -417,6 +426,10 @@
         HX_RELEASE(m_pSiteSupplier);
         HX_RELEASE(m_pClientEngine);
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+        HX_RELEASE(m_pPowerSave);
+        HX_RELEASE(m_pScheduler3);
+#endif /*HELIX_FEATURE_POWER_SAVE*/
         if(m_pPlayerControl != NULL)
         {
             if (m_pPlayerControl->m_pHXPlayer)
@@ -452,6 +465,10 @@
     , m_clientTid(0)
     , m_bPlayPending(FALSE)
     , m_bSurfaceCreated(FALSE)
+#ifdef HELIX_FEATURE_POWER_SAVE
+    ,m_pPowerSave(NULL)
+    ,m_pScheduler3(NULL)
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 {
     m_pSiteSupplier = NULL;
     m_pPrefs = NULL;
@@ -527,6 +544,13 @@
     {
         User::Leave(KErrNoMemory);
     }
+#ifdef HELIX_FEATURE_POWER_SAVE
+	//no need to  check the memory allocation here. It is done above.
+    m_pClientEngine->QueryInterface(IID_IHXPowerSave, (void**)&m_pPowerSave);
+
+    HX_RELEASE(m_pScheduler3);
+    QueryInterface(IID_IHXScheduler3, (void**)&m_pScheduler3);
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 
     InitAdviseSinks();
     SetupAPSelectorL();
@@ -1049,6 +1073,33 @@
 	return m_clientTid;
 }
 
+void HXMMFStateCtrl::StartPowerSave()
+{
+    HX_RESULT retVal = HXR_FAIL;
+
+
+#ifdef HELIX_FEATURE_POWER_SAVE
+    HXLOGL2( HXLOG_SMMF, "HXMMFStateCtrl::StartPowerSave  m_pPowerSave:%p", m_pPowerSave);
+    if(m_pPowerSave)
+    {
+        retVal = m_pPowerSave->StartPowerSave();
+    }
+#endif
+
+}
+
+
+void HXMMFStateCtrl::EndPowerSave()
+{
+#ifdef HELIX_FEATURE_POWER_SAVE
+    HXLOGL2( HXLOG_SMMF, "HXMMFStateCtrl::EndPowerSave  m_pPowerSave:%p", m_pPowerSave); 
+    if(m_pPowerSave)
+    {
+        m_pPowerSave->EndPowerSave();
+    }
+#endif
+
+}
 //Ensure timer is active.
 void HXMMFStateCtrl::SetOnPostSeekTimer()
 {  


---------------------------------------------------------------------------------------------------------

Index: hxmmfaudioctrl.h
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/audiocontroller/hxmmfaudioctrl.h,v
retrieving revision 1.9.32.5
diff -u -r1.9.32.5 hxmmfaudioctrl.h
--- hxmmfaudioctrl.h	4 May 2010 00:23:39 -0000	1.9.32.5
+++ hxmmfaudioctrl.h	31 Aug 2010 18:58:24 -0000
@@ -100,6 +100,7 @@
         virtual void PauseL();
         virtual void StopL();
         virtual void PrimeL();
+        virtual void SetPositionL(const TTimeIntervalMicroSeconds& aPosition);
 
         //
         //   MMMFAudioPlayControllerCustomCommandImplementor Methods


----------------------------------------------------------------------------------------------------------

Index: hxmmfaudioctrl.cpp
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/audiocontroller/hxmmfaudioctrl.cpp,v
retrieving revision 1.32.4.10
diff -u -r1.32.4.10 hxmmfaudioctrl.cpp
--- hxmmfaudioctrl.cpp	1 Jun 2010 04:04:20 -0000	1.32.4.10
+++ hxmmfaudioctrl.cpp	31 Aug 2010 19:00:42 -0000
@@ -258,6 +258,7 @@
         
         ResumeScheduler();
 
+        m_pStateCtrl->StartPowerSave();
 		
         if(m_uStartWindowPosition == TTimeIntervalMicroSeconds(0) &&
             m_uEndWindowPosition == DurationL())
@@ -976,7 +977,12 @@
 		}
         User::Leave(lError);
     }
-
+    // Pause the scheduler
+    if(m_bLocalPlayback)
+    {
+        HXLOGL1( HXLOG_SMMF, "CHXAudioController::AddDataSourceL() Pausing Scheduler");
+        PauseScheduler();
+    }
 }
 
 
@@ -1106,5 +1112,18 @@
 {
     return KErrNotSupported;
 }
+void
+CHXAudioController::SetPositionL( const TTimeIntervalMicroSeconds& aPosition )
+{	
+    HXLOGL1(HXLOG_SMMF, "CHXAudioController::SetPositionL() ");
+	
+    if(m_pStateCtrl != NULL)
+    {
+        m_pStateCtrl->EndPowerSave();
+	
+        HXMMFBaseCtrl::SetPositionL ( aPosition );
+    }
+
+}
     
 // End of File

---------------------------------------------------------------------------------------------------------

Index: hxmmfctrlimpl.cpp
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/videocontroller/hxmmfctrlimpl.cpp,v
retrieving revision 1.91.4.12
diff -u -r1.91.4.12 hxmmfctrlimpl.cpp
--- hxmmfctrlimpl.cpp	12 Jul 2010 16:43:47 -0000	1.91.4.12
+++ hxmmfctrlimpl.cpp	31 Aug 2010 19:04:24 -0000
@@ -1331,7 +1331,7 @@
     HXLOGL1(HXLOG_SMMF, "HXMMFCtrlImpl::OnPresentationClosed(m_closePlayer[%d])",m_closePlayer);
 
     TInt isLive = 0;
-
+    HXBOOL bPauseSched = FALSE;
 
     // seek the datasource to initial position.
     if (m_pDataSource)
@@ -1353,24 +1353,36 @@
         {
             SendEvent( m_nextEvent, m_ulLastError );
 
-            if(m_bLocalPlayback && m_ulLastError == HXR_OK)
-            {
-                PauseScheduler();
-            }
+            bPauseSched = TRUE;
 
         }
         m_nextEvent = ErrorEvent;
 
     }
-    else if (m_pMetaData)
+    else
+    {
+        if (m_pMetaData)
     {
         m_pMetaData->FindMetaDataValueByName("LiveStream",isLive);
 
         if (m_nextEvent == ErrorEvent && isLive)
         {
             SendEvent( ErrorEvent, HXR_CLOSED );
+            } 
+            else if(!isLive) 
+            {
+                bPauseSched = TRUE;
+            }
+        }
+        else
+        {
+            bPauseSched = TRUE;
         }
     }
+    if(m_bLocalPlayback && m_ulLastError == HXR_OK && bPauseSched)
+    {
+        PauseScheduler();
+    }
 }
 
---------------------------------------------------------------------------------------------------------------


Index: hxcore.h
===================================================================
RCS file: /cvsroot/common/include/hxcore.h,v
retrieving revision 1.24.2.1
diff -u -r1.24.2.1 hxcore.h
--- hxcore.h	18 Sep 2009 04:48:22 -0000	1.24.2.1
+++ hxcore.h	26 Aug 2010 15:31:58 -0000
@@ -2412,81 +2412,6 @@
  *
  */
 
-DEFINE_GUID(IID_IHXPowerSave, 0xf52067d2, 0xbf0b, 0x4081, 0xb3, 0x6f, 0xca, 0xee, 0x79, 0x24, 0x21, 0x9a);
-
-#undef  INTERFACE
-#define INTERFACE   IHXPowerSave
-
-DECLARE_INTERFACE_(IHXPowerSave, IUnknown)
-{
-     /*
-      * IUnknown methods
-      */
-     STDMETHOD(QueryInterface)		(THIS_
-					 REFIID riid,
-					 void** ppvObj) PURE;
-
-     STDMETHOD_(ULONG32,AddRef)		(THIS) PURE;
-
-     STDMETHOD_(ULONG32,Release)	(THIS) PURE;
-
-     /*
-      * IHXPowerSave methods
-      */
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::StartPowerSave
-      * Purpose:
-      *     same as EventOccurred with HX_POWERSAVE_ON
-      */
-     STDMETHOD(StartPowerSave)			(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::EndPowerSave
-      * Purpose:
-      *     same as EventOccurred with HX_POWERSAVE_OFF
-      */
-     STDMETHOD(EndPowerSave)			(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::IsInPowerSave
-      * Purpose:
-      *	    Check whether it is in power save mode. 
-      *     TRUE if operation on power save mode, FALSE otherwise
-      */
-     STDMETHOD_(HXBOOL,IsInPowerSave)		(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::CanStartPowerSave
-      * Purpose:
-      *     Check whether power-save-mode can be turned on.
-      *     TRUE if power save mode can be turned on at the time of the call.
-      */
-     STDMETHOD_(HXBOOL,CanStartPowerSave)	(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::GetWakeUpInterval
-      * Purpose:
-      *     Get time interval engine will nomally wake up in to operate
-      */
-     STDMETHOD_(ULONG32,GetWakeUpInterval)	(THIS) PURE;
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::SetWakeUpInterval
-      * Purpose:
-      *     Set time interval engine will nomally wake up in to operate  (use 
-      *     this only to override default)
-      */
-     STDMETHOD_(ULONG32,SetWakeUpInterval)	(THIS_ 
-						 ULONG32 /*IN*/ ulWakeUpInterval) PURE;
-
-};
-
 #include "hxcomptr.h"
 DEFINE_SMART_PTR(IHXStream)
 DEFINE_SMART_PTR(IHXStream2)
@@ -2517,9 +2442,6 @@
 DEFINE_SMART_PTR(IHXPlayerPresentation)
 DEFINE_SMART_PTR(IHXCoreMutex)
 DEFINE_SMART_PTR(IHXMacBlitMutex)
-#if defined(HELIX_FEATURE_POWER_SAVE)
-  DEFINE_SMART_PTR(IHXPowerSave)
-#endif /* defined(HELIX_FEATURE_POWER_SAVE) */
 
 #if defined _UNIX && !defined (_VXWORKS)
 DEFINE_SMART_PTR(IHXClientEngineSelector)

-------------------------------------------------------------------------------------------------------------------

Index: hxiids.h
===================================================================
RCS file: /cvsroot/common/include/hxiids.h,v
retrieving revision 1.168.4.4
diff -u -r1.168.4.4 hxiids.h
--- hxiids.h	7 Jul 2010 23:19:56 -0000	1.168.4.4
+++ hxiids.h	9 Aug 2010 16:29:30 -0000
@@ -425,6 +425,8 @@
 DEFINE_GUID_ENUM(IID_IHXPersistentComponent,    0x00000416, 0x901, 0x11d1, 0x8b, 0x6, 0x0, 0xa0, 0x24, 0x40, 0x6d, 0x59)
 DEFINE_GUID_ENUM(IID_IHXExternalSystemClock,            0x6de011a7, 0xef05, 0x417b, 0x93, 0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd5)
 DEFINE_GUID_ENUM(IID_IHXPowerSave,                      0xf52067d2, 0xbf0b, 0x4081, 0xb3, 0x6f, 0xca, 0xee, 0x79, 0x24, 0x21, 0x9a)
+DEFINE_GUID_ENUM(IID_IHXTimeLineLimit, 
+				0xb91a83e0, 0xef48, 0x11de, 0xaa, 0xca, 0x0, 0x2, 0xa5, 0xd5, 0xc5, 0x1b)
 // $Private:
 DEFINE_GUID_ENUM(IID_IHXSourceBufferingStats,       0x00000418, 0x901, 0x11d1, 0x8b, 0x6, 0x0, 0xa0, 0x24, 0x40, 0x6d, 0x59)
 DEFINE_GUID_ENUM(IID_IHXSourceBufferingStats2,       0x00000418, 0x901, 0x11d1, 0x8b, 0x6, 0x0, 0xa0, 0x24, 0x40, 0x6d, 0x5a)

--------------------------------------------------------------------------------------------------------------------

Index: hxengin.h
===================================================================
RCS file: /cvsroot/common/include/hxengin.h,v
retrieving revision 1.40
diff -u -r1.40 hxengin.h
--- hxengin.h	5 May 2009 16:26:33 -0000	1.40
+++ hxengin.h	9 Aug 2010 16:29:09 -0000
@@ -311,6 +311,8 @@
     STDMETHOD_(HXBOOL, AreImmediatesPending)(THIS) PURE;
 };
 
+#undef  INTERFACE
+#define INTERFACE   IHXScheduler3
 DECLARE_INTERFACE_(IHXScheduler3, IUnknown)
 {
     /*

--------------------------------------------------------------------------------------------------------------------
Index: helix-client-symbian-4-common.pfi
===================================================================
RCS file: /cvsroot/ribosome/build/umakepf/helix-client-symbian-4-common.pfi,v
retrieving revision 1.5
diff -u -r1.5 helix-client-symbian-4-common.pfi
--- helix-client-symbian-4-common.pfi	12 May 2010 19:25:47 -0000	1.5
+++ helix-client-symbian-4-common.pfi	7 Sep 2010 19:20:22 -0000
@@ -67,3 +67,6 @@
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_S60_AVKON')
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_VIDEOCTRL_PKG')
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_PHONON_PKG')
+
+project.AddDefines('HELIX_FEATURE_POWER_SAVE')
+

--------------------------------------------------------------------------------------------------------------------

Index: helix-client-symbian-4-integration-common.pfi
===================================================================
RCS file: /cvsroot/ribosome/build/umakepf/helix-client-symbian-4-integration-common.pfi,v
retrieving revision 1.6
diff -u -r1.6 helix-client-symbian-4-integration-common.pfi
--- helix-client-symbian-4-integration-common.pfi	12 May 2010 19:48:50 -0000	1.6
+++ helix-client-symbian-4-integration-common.pfi	7 Sep 2010 19:20:38 -0000
@@ -75,3 +75,5 @@
 project.RemoveDefines('HELIX_FEATURE_MMF_CUSTOM_COMMAND')
 project.RemoveDefines('HELIX_FEATURE_MMF_STREAM_CONTROL')
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_VIDEOCTRL_PKG')
+
+project.AddDefines('HELIX_FEATURE_POWER_SAVE')


 
 

-------------- next part --------------
#ifndef _HXPOWERSAVE_H_
#define _HXPOWERSAVE_H_




typedef _INTERFACE IHXPowerSave IHXPowerSave;

/****************************************************************************
*
*  Interface:
*
*	IHXPowerSave
*
*  Purpose:
*
*	Interface for IHXPowerSave objects.
*
*  IID_IHXPowerSave:
*
*   {F52067D2-BF0B-4081-B36F-CAEE7924219A}
*
*/

#undef INTERFACE
#define INTERFACE IHXPowerSave
DEFINE_GUID(IID_IHXPowerSave, 0xf52067d2, 0xbf0b, 0x4081, 0xb3, 0x6f, 0xca, 0xee, 0x79, 0x24, 0x21, 0x9a);

DECLARE_INTERFACE_(IHXPowerSave, IUnknown)
{

    /* IUnknown methods. */
    STDMETHOD(QueryInterface)   (THIS_ REFIID riid, void** ppvObj) PURE;
    STDMETHOD_(ULONG32,AddRef)  (THIS) PURE;
    STDMETHOD_(ULONG32,Release) (THIS) PURE;

	STDMETHOD(StartPowerSave) (THIS) PURE;
	STDMETHOD(EndPowerSave ) (THIS) PURE;
	STDMETHOD_(HXBOOL,IsInPowerSave) (THIS) PURE;
	STDMETHOD_(HXBOOL,CanStartPowerSave) (THIS) PURE;
	STDMETHOD_(ULONG32,GetWakeUpInterval ) (THIS) PURE;
	STDMETHOD(SetWakeUpInterval  ) (THIS_ ULONG32 ulWakeUpInterval ) PURE;
};


#endif /*_HXPOWERSAVE_H_*/
-------------- next part --------------
#ifndef _HXTIMELINELIMIT_H_
#define _HXTIMELINELIMIT_H_



typedef _INTERFACE IHXTimeLineLimit IHXTimeLineLimit;

/****************************************************************************
*
*  Interface:
*
*	IHXTimeLineLimit
*
*  Purpose:
*
*	Interface for IHXTimeLineLimit objects.
*
*  IID_IHXTimeLineLimit:
*
*	{b91a83e0-ef48-11de-aaca-0002a5d5c51b)
*
*/

#undef INTERFACE
#define INTERFACE IHXTimeLineLimit

DEFINE_GUID(IID_IHXTimeLineLimit, 0xb91a83e0, 0xef48, 0x11de, 0xaa, 0xca, 0x0, 0x2, 0xa5, 0xd5, 0xc5, 0x1b);

DECLARE_INTERFACE_(IHXTimeLineLimit, IUnknown)
{
	/* IUnknown methods. */
    STDMETHOD(QueryInterface)   (THIS_ REFIID riid, void** ppvObj) PURE;
    STDMETHOD_(ULONG32,AddRef)  (THIS) PURE;
    STDMETHOD_(ULONG32,Release) (THIS) PURE;
	
	STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs )PURE;
	STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs )PURE;
	STDMETHOD(ResetLimit) (THIS) PURE;
};

#endif /*_HXTIMELINELIMIT_H_*/
From xiaolin.lliu at nokia.com  Fri Sep 10 10:30:58 2010
From: xiaolin.lliu at nokia.com (xiaolin.lliu@nokia.com)
Date: Fri Sep 10 16:56:06 2010
Subject: [Helix-client-dev] RESEND: [datatype-dev] [Client-dev]
 [Clientapps-dev] CR: Symbian
 Add  Power Save Support to Brizo420 and head
Message-ID: 

Skipped content of type multipart/alternative-------------- next part --------------

Index: mdfauddevice.h
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfauddevice.h,v
retrieving revision 1.10.10.1
diff -u -r1.10.10.1 mdfauddevice.h
--- mdfauddevice.h	9 Feb 2010 17:55:23 -0000	1.10.10.1
+++ mdfauddevice.h	31 Aug 2010 19:44:43 -0000
@@ -70,6 +70,10 @@
 #include "mdfaudfmt.h"
 #include "mdfauddata.h"
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxTimelineLimit.h"
+#include  "hxPowerSave.h"
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 // mdf device uses invalid value for initialization
 #define MDFDEVICE_INVALID_VOLUME -1 
 
@@ -80,6 +84,11 @@
                             public CActive,
                             public CHXMDFAudioDeviceObserver,
                             public IHXPropWatchResponse
+#ifdef HELIX_FEATURE_POWER_SAVE
+                           ,public IHXPowerSave
+                           ,public IHXTimeLineLimit
+                           ,public CHXPowerSaveAudDeviceObserver
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 {
 public:
     // factory method
@@ -148,7 +157,28 @@
     void SetStreamFinished(HXBOOL bEndOfStream);
 
     void StreamFinished();
-
+#ifdef HELIX_FEATURE_POWER_SAVE
+	/*Implement IHXTimeLineLimit*/
+    STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs );
+    STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs );
+    STDMETHOD(ResetLimit) (THIS);
+
+    /*Implement IHXPowerSave*/
+    STDMETHOD(StartPowerSave) (THIS);
+    STDMETHOD(EndPowerSave ) (THIS);
+    STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
+    STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
+    STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
+    STDMETHODIMP SetWakeUpInterval(THIS_ ULONG32 ulWakeUpInterval );
+    //
+    // CHXPowerSaveAudDeviceObserver methods
+    //
+    virtual void HighWaterMark();
+    virtual void LowWaterMark();
+protected:
+    HXBOOL IsDueStreamLimit();
+    void LoadPowerSaveCfg();
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 private:
     CHXMDFAudioDevice(HXMDFAudioFormat* pAudioFormat);      //constructor
     HX_RESULT Construct();          //two-phase constructor
@@ -179,6 +209,8 @@
 
     //Timing
     UINT32              m_ulAudioTimeOffset;    //rendering time
+    UINT32              m_ulCurrPlayTime;
+    HXBOOL              m_bDisableOnTimeSyncTimer;
         
     // buffered frames
     CHXSimpleList       m_bufferList;           //frames received from decoder
@@ -206,6 +238,24 @@
 
     HXBOOL              m_bEndOfStream; 
     HXBOOL              m_bEndOfStreamSent; 
+#ifdef HELIX_FEATURE_POWER_SAVE
+private:
+    IHXScheduler3*	m_pScheduler3;
+    HXBOOL m_bIsInPowerSave;
+    UINT32 m_ulWakeUpInterval;
+    UINT32 m_ulLowWaterMark;
+    UINT32 m_ulLimitDeviceInMs;
+    //last packet time passed to mdfDevsound Q
+    UINT32 m_ulLastAudioWrite;
+
+    //  Stat for power save config
+    UINT32 m_ulSchedulerPausedTime;
+    UINT32 m_ulSchedulerResumedTime;
+    UINT32 m_ulTotalSchedSleepTime;
+    UINT32 m_ulTotalSchedRunTime;
+
+
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 };
 
 ------------------------------------------------------------------------------------------------------------------

Index: mdfauddevice.cpp
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfauddevice.cpp,v
retrieving revision 1.19.4.7
diff -u -r1.19.4.7 mdfauddevice.cpp
--- mdfauddevice.cpp	8 Jun 2010 08:40:06 -0000	1.19.4.7
+++ mdfauddevice.cpp	31 Aug 2010 20:05:03 -0000
@@ -50,9 +50,15 @@
 #include "hxassert.h"
 #include "mdfauddevice.h"
 #include "mdfdebug.h"
+#include "hxtick.h" //HX_GET_BETTERTICKCOUNT()
 #include "hxprefutil.h"
 #include "hal.h" // for HAL::Get of ENanoTickPeriod
 
+#define DEFAULT_POWER_SAVE_HWM_MS   6000 //values are set in ms
+#define DEFAULT_POWER_SAVE_LWM_MS   2000 //values are set in ms
+// Offset is added to the HWM when wakeupinterval is calculated
+#define POWER_SAVE_HWM_OFFSET_MS       500
+
 
 static UINT32 Scale(UINT32 v, UINT32 f0, UINT32 f1, UINT32 t0, UINT32 t1);
 
@@ -122,6 +128,8 @@
         m_nBytesPCMToPlay(0),
         m_playing(FALSE),
         m_ulAudioTimeOffset(0),
+        m_ulCurrPlayTime(0),
+        m_bDisableOnTimeSyncTimer(FALSE),
         m_pAudioFormat(pAudioFormat),
         m_pErrorMessage(NULL),
         m_bDevTimeNeeded(TRUE),
@@ -132,6 +140,18 @@
         m_pPropWatch(NULL),
         m_bEndOfStream(FALSE)
         ,m_bEndOfStreamSent(FALSE)
+#ifdef HELIX_FEATURE_POWER_SAVE
+        ,m_pScheduler3(NULL)
+        ,m_bIsInPowerSave(FALSE)
+        ,m_ulWakeUpInterval (DEFAULT_POWER_SAVE_HWM_MS)
+        ,m_ulLowWaterMark(DEFAULT_POWER_SAVE_LWM_MS)
+        ,m_ulLimitDeviceInMs (0)
+        ,m_ulLastAudioWrite(0)
+        ,m_ulSchedulerPausedTime(0)
+        ,m_ulSchedulerResumedTime(HX_GET_BETTERTICKCOUNT())
+        ,m_ulTotalSchedSleepTime(0)
+        ,m_ulTotalSchedRunTime(0)
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 {
     //- activate active object
     CActiveScheduler::Add(this);
@@ -152,6 +172,18 @@
 CHXMDFAudioDevice::~CHXMDFAudioDevice()
 {
     HXLOGL4(HXLOG_MDFA,"mdfdev:~mdfdev <");
+#ifdef HELIX_FEATURE_POWER_SAVE
+    m_ulSchedulerPausedTime = HX_GET_BETTERTICKCOUNT();
+    UINT32 ulCurrSchedRunTime = m_ulSchedulerPausedTime - m_ulSchedulerResumedTime;
+    m_ulTotalSchedRunTime += ulCurrSchedRunTime;
+    UINT32 ulTotalSchedTime = m_ulTotalSchedRunTime + m_ulTotalSchedSleepTime;
+    HXLOGL1(HXLOG_MDFA,"------ Statistics of Power Save ----------");
+    HXLOGL1(HXLOG_MDFA, "CHXMDFAudioDevice[%p]::~CHXMDFAudioDevice PSave TotalRunTime:%lu TotSleepTime:%lu", this, m_ulTotalSchedRunTime, m_ulTotalSchedSleepTime);
+    HXLOGL1(HXLOG_MDFA, "CHXMDFAudioDevice[%p]::~CHXMDFAudioDevice PSave TotalRunTime:%lu Percent TotSleepTime:%lu percent", this,
+        ((m_ulTotalSchedRunTime *100 /ulTotalSchedTime)) , ((m_ulTotalSchedSleepTime*100 /ulTotalSchedTime)) );
+    HXLOGL1(HXLOG_MDFA,"------------------------------------------");
+    HX_RELEASE(m_pScheduler3);
+#endif // End of #ifdef HELIX_FEATURE_POWER_SAVE
     Close(TRUE);
     m_iTimer.Close();
 
@@ -209,6 +241,10 @@
             { GET_IIDHANDLE(IID_IHXTimelineWatcher), (IHXTimelineWatcher*)this },
             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXAudioDevice*)this },
             { GET_IIDHANDLE(IID_IHXPropWatchResponse), (IHXPropWatchResponse*)this },
+#ifdef HELIX_FEATURE_POWER_SAVE
+            { GET_IIDHANDLE(IID_IHXTimeLineLimit), (IHXTimeLineLimit*)this },
+            { GET_IIDHANDLE(IID_IHXPowerSave), (IHXPowerSave*)this },
+#endif /*HELIX_FEATURE_POWER_SAVE*/
         };
 
     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
@@ -295,6 +331,9 @@
         HX_RELEASE(m_pErrorMessage);
         m_pContext->QueryInterface(IID_IHXErrorMessages, (void **)&m_pErrorMessage);
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+        LoadPowerSaveCfg();
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
     }
     else
     {
@@ -351,8 +390,8 @@
 
 			m_bDevTimeNeeded = TRUE;	//now we need Dev Time
 				
-            GetCurrentAudioTime(ulAudioTime);
-            m_pDeviceResponse->OnTimeSync(ulAudioTime);
+            m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+            m_pDeviceResponse->OnTimeSync(m_ulCurrPlayTime);
         }
 
         //Set timer for next OnTimeSync callback
@@ -564,8 +603,8 @@
     if(m_pDeviceResponse)
     {
         ULONG32 ulAudioTime = 0;
-        GetCurrentAudioTime(ulAudioTime);
-        m_pDeviceResponse->OnTimeSync(ulAudioTime);
+        m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+        m_pDeviceResponse->OnTimeSync(m_ulCurrPlayTime);
     }
 
     DoSetTimer();
@@ -601,6 +640,10 @@
             HXLOGL4(HXLOG_MDFA,"mdfdev:write .. encoded data added");
             m_bufferList.RemoveHead();
             m_readyList.AddTail(pAudioData);
+#if defined HELIX_FEATURE_POWER_SAVE
+            m_ulLastAudioWrite = pAudioData->m_ulAudioTime-m_ulAudioTimeOffset;
+            m_pDevSound->SetLastRecvdEncodedData(m_ulLastAudioWrite);
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 
 #if defined(HELIX_FEATURE_LOGLEVEL_4) || defined(HELIX_FEATURE_LOGLEVEL_ALL)
             if ( pAudioData )
@@ -615,11 +658,12 @@
     {
         m_nBytesPCMToPlay += dataSize;
         
-        while(m_nBytesPCMToPlay >= m_pAudioFormat->m_uBytesPerFrame && m_pAudioFormat->m_uBytesPerFrame)
+        while(m_nBytesPCMToPlay >= m_pAudioFormat->m_uBytesPerFrame && m_pAudioFormat->m_uBytesPerFrame
+                && m_bEndOfStreamSent) 
         {
             m_readyList.AddTail(&m_pAudioFormat->m_fillerFrame);
             m_nBytesPCMToPlay -= m_pAudioFormat->m_uBytesPerFrame;
-            HXLOGL4(HXLOG_MDFA,"mdfdev:write .. adding filler frame");
+            HXLOGL4(HXLOG_MDFA,"mdfdev:write .. adding filler frame m_bEndOfStreamSent:%d", m_bEndOfStreamSent);
         }
     }
 
@@ -708,6 +752,7 @@
     //reset SecureOutput settings
     m_bSecureOutputChanged = FALSE;
 
+    m_ulCurrPlayTime = 0; 
     // stop device.
     if (m_pDevSound)
     {
@@ -767,11 +812,11 @@
 
 	if (pAudioFormat) {
         if (m_pAudioFormat->m_uChannels == pAudioFormat->uChannels &&
-        		m_pAudioFormat->m_uBitsPerSample == pAudioFormat->uBitsPerSample &&
-        		m_pAudioFormat->m_ulSamplesPerSec == pAudioFormat->ulSamplesPerSec) {
+            m_pAudioFormat->m_uBitsPerSample == pAudioFormat->uBitsPerSample &&
+            m_pAudioFormat->m_ulSamplesPerSec == pAudioFormat->ulSamplesPerSec) {
         			res = HXR_OK;
         		}
-    }
+	}
     return res;
 }
 
@@ -784,32 +829,55 @@
 
     HX_RESULT hxr = HXR_OK;
 
-    UINT32 systemTime=(UINT32)(((UINT64)User::NTickCount() * 1000) / m_systemTickPeriodInMicroSecond); 
+  //  UINT32 systemTime=(UINT32)(((UINT64)User::NTickCount() * 1000) / m_systemTickPeriodInMicroSecond); 
 
-    if (m_bDevTimeNeeded) {
-        hxr = m_pDevSound->GetCurrentPlayTime(ulCurrentTime);  //Dev Time
-        m_devTime = ulCurrentTime;
-        if (m_ulLastTime>ulCurrentTime) {
+#ifdef HELIX_FEATURE_POWER_SAVE
+    //  If scheduler is not running, the playback time is not current.
+    //  Update the current playback time
+    if(m_bIsInPowerSave && m_pScheduler3 && m_pScheduler3->IsPaused())
+    {
+        hxr = m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+        ulCurrentTime = m_ulCurrPlayTime;
+    }
+    else	
+#endif 
+    {
+        UINT32 systemTime=(UINT32)(((UINT64)User::NTickCount() * 1000) / m_systemTickPeriodInMicroSecond); 
+        if (m_bDevTimeNeeded)             
+        {
+            hxr = m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);  //Dev Time
+            ulCurrentTime = m_ulCurrPlayTime;
+            m_devTime = ulCurrentTime;
+            if (m_ulLastTime>ulCurrentTime) 
+            {
             // Device time ahead of computed time:
             //   return last computed time
-            ulCurrentTime=m_ulLastTime;
-        }
-        m_systemTimeMark = systemTime;
-        m_bDevTimeNeeded = FALSE;				//no need to check Dev Time.
-    } else {
-        // Don't ask time to device: compute using elapsed system time
-        LONG32 elapse = systemTime - m_systemTimeMark;
-        // Case of 32 bit counter overflow
-        if (elapse < 0) elapse= -elapse;
-        ulCurrentTime = m_devTime + elapse;		//interpolation
-        if (m_ulLastTime>ulCurrentTime) {
+                ulCurrentTime=m_ulLastTime;
+            }
+            m_systemTimeMark = systemTime;
+            m_bDevTimeNeeded = FALSE;				//no need to check Dev Time.
+        } 
+        else 
+        {
+            // Don't ask time to device: compute using elapsed system time
+            LONG32 elapse = systemTime - m_systemTimeMark;
+            // Case of 32 bit counter overflow
+            if (elapse < 0) elapse= -elapse;
+            ulCurrentTime = m_devTime + elapse;		//interpolation xaliu
+
+            if (m_ulLastTime>ulCurrentTime) 
+			{
             // New computed time still behind last computed time:
             //   return last computed time until new computed time goes ahead
-            ulCurrentTime=m_ulLastTime;
-        } else {
-            m_ulLastTime=ulCurrentTime;
-        }
-     } 
+                ulCurrentTime=m_ulLastTime;
+            } 
+            else 
+            {
+                m_ulLastTime=ulCurrentTime;
+            }
+        } 
+    }
+
 #if defined(HELIX_FEATURE_DRM_SECURE_OUTPUT)
 	if(m_bSecureOutputChanged) 
 	{
@@ -893,6 +961,7 @@
     HXLOGL4(HXLOG_MDFA,"mdfdeV:setStartT <> %d", ulStartTime);
 
     m_ulAudioTimeOffset = ulStartTime;
+    m_pDevSound->SetAudioTimeOffset(m_ulAudioTimeOffset); 
 }
 
 void CHXMDFAudioDevice::SetStreamFinished(HXBOOL bEndOfStream)
@@ -935,7 +1004,7 @@
 {
     HXLOGL4(HXLOG_MDFA,"mdfdeV:dosettimer <");
 
-    if( !IsActive())
+    if( (!IsActive()) && (!m_bDisableOnTimeSyncTimer)) 
     {
         //HXLOGL4(HXLOG_MDFA, "mdfdeV:dosettimer .. set timer here. %d", iStatus.Int());
         m_iTimer.After(iStatus, m_TimeSyncPeriodInMs * 1000);
@@ -953,7 +1022,9 @@
     HXLOGL4(HXLOG_MDFA, "mdfdeV:OnDeviceError <");
 
     HX_ASSERT(m_pErrorMessage != NULL);
-
+#ifdef HELIX_FEATURE_POWER_SAVE
+    EndPowerSave();
+#endif /*HELIX_FEATURE_POWER_SAVE*/
     // Report error to Error Messages
     if(m_pErrorMessage)
     {
@@ -1014,6 +1085,227 @@
 }
 
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+void CHXMDFAudioDevice::LoadPowerSaveCfg()
+{
+    if(m_pContext != NULL)
+    {
+        IHXPreferences* pPreference = NULL;
+        if(SUCCEEDED(m_pContext->QueryInterface(IID_IHXPreferences, (void**) &pPreference)))
+        {
+            // High water mark is same as wake up interval
+            UINT32 hwm = 0;
+            UINT32 lwm = 0;
+            if (SUCCEEDED(ReadPrefUINT32(pPreference, "PowerSaveHWM", hwm)) 
+                    && SUCCEEDED(ReadPrefUINT32(pPreference, "PowerSaveLWM", lwm)))            
+            {
+                if (lwm < hwm)
+                {
+                    m_ulWakeUpInterval = hwm;
+                    m_ulLowWaterMark = lwm;
+                }
+            }
+            HX_RELEASE(pPreference);
+        }
+    }
+    HXLOGL2(HXLOG_MDFA, "mdfdeV:LoadPowerSaveCfg HWM:%lu LWM:%lu ", m_ulWakeUpInterval, m_ulLowWaterMark);
+}
+HXBOOL CHXMDFAudioDevice::IsDueStreamLimit()
+{
+    HXBOOL bReachingStreamLimit = FALSE;
+    if((m_bIsInPowerSave) && m_ulLimitDeviceInMs != 0)
+    {
+        ULONG32 ulAudioTime = 0;
+        GetCurrentAudioTime(ulAudioTime);
+        //get the time left
+        ulAudioTime = (ULONG32)m_ulLimitDeviceInMs - ulAudioTime;
+
+        //if we are reaching the end of file
+        if( ulAudioTime < (ULONG32)m_ulWakeUpInterval)
+        {
+            bReachingStreamLimit = TRUE;
+        }
+    }
+
+    HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::IsDueStreamLimit bReachingStreamLimit[%d] ", this, bReachingStreamLimit);
+
+    return bReachingStreamLimit;
+}
+STDMETHODIMP
+CHXMDFAudioDevice::SetLimit (UINT32 ulLimitInMs )
+{
+    m_ulLimitDeviceInMs = ulLimitInMs;
+
+    HX_RESULT retVal = HXR_OK;
+    HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::SetLimit retVal=%x ", this, retVal);
+    return retVal;
+}
+
+STDMETHODIMP
+CHXMDFAudioDevice::GetLimit (UINT32 &ulLimitInMs )
+{
+   ulLimitInMs = m_ulLimitDeviceInMs;
+
+   HX_RESULT retVal = HXR_OK;
+   HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::GetLimit retVal=%x ", this, retVal);
+   return retVal;
+}
+
+STDMETHODIMP
+CHXMDFAudioDevice::ResetLimit ()
+{
+    m_ulLimitDeviceInMs = 0;
+
+    return HXR_OK;
+}
+
+
+/*Implement IHXPowerSave*/
+STDMETHODIMP
+CHXMDFAudioDevice::StartPowerSave()
+{
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::StartPowerSave ", this);
+
+    HX_RESULT retVal = HXR_OK;
+    if(!m_bIsInPowerSave)
+    {
+        HX_RELEASE(m_pScheduler3);
+        retVal = m_pContext->QueryInterface(IID_IHXScheduler3, (void**) &m_pScheduler3);
+
+        if(m_pScheduler3 != NULL)
+        {
+            //set value to true for active
+            m_bIsInPowerSave = TRUE;
+            m_pDevSound->SetPowerSaveConfig((CHXPowerSaveAudDeviceObserver*)this, m_ulWakeUpInterval, m_ulLowWaterMark);
+        } // End of if(m_pScheduler3 != NULL)
+        else 
+        {
+            HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::StartPowerSave Can not query Scheduler3");
+            retVal = HXR_FAIL;
+        }
+    }
+
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::StartPowerSave retVal=%x ", this, retVal);
+
+    return retVal;
+}
+
+
+STDMETHODIMP
+CHXMDFAudioDevice::EndPowerSave()
+{
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::EndPowerSave ", this);
+
+    HX_RESULT retVal = HXR_OK;
+    if(m_bIsInPowerSave)
+    {
+        HXLOGL3( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::EndPowerSave calling ResumeScheduler ", this);
+        LowWaterMark();
+        m_pDevSound->SetPowerSaveConfig(NULL, m_ulWakeUpInterval, m_ulLowWaterMark); //as such LowWaterMArk won't be called
+        m_bIsInPowerSave = FALSE;
+
+    } // End of if(m_bIsInPowerSave)
+
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::EndPowerSave retVal=%x ", this, retVal);
+
+    return retVal;
+}
+STDMETHODIMP_(HXBOOL)
+CHXMDFAudioDevice::IsInPowerSave()
+{
+    HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::IsInPowerSave m_bIsInPowerSave=%d ", this, m_bIsInPowerSave);
+    return m_bIsInPowerSave;
+}
+
+STDMETHODIMP_(HXBOOL)
+CHXMDFAudioDevice::CanStartPowerSave()
+{
+    HXBOOL bCanStart = TRUE;
+    HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::CanStartPowerSave bCanStart:%d", this, bCanStart);
+    return bCanStart;
+}
+
+STDMETHODIMP_(ULONG32)
+CHXMDFAudioDevice::GetWakeUpInterval()
+{
+    ULONG32 ulWakeUpInterval = m_ulWakeUpInterval;
+    // Adding an offset, so that the source does not stop sending data based on old playback time.
+    ulWakeUpInterval += POWER_SAVE_HWM_OFFSET_MS;
+    HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::GetWakeUpInterval m_ulWakeUpInterval=%lu ", this, m_ulWakeUpInterval);
+
+    return ulWakeUpInterval;
+}
+STDMETHODIMP 
+CHXMDFAudioDevice::SetWakeUpInterval(ULONG32 ulWakeUpInterval )
+{
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::SetWakeUpInterval --WARNING-- luWakeUpInterval=%lu", this, ulWakeUpInterval);
+	//
+    // Does not accept other values from core
+    //
+    return HXR_FAIL;	
+}
+void CHXMDFAudioDevice::HighWaterMark()
+{
+    if(m_bIsInPowerSave)
+    {
+        HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::HighWaterMark calling IsDueStreamLimit()", this);
+
+        //when reaching the end of file we don't want to go to sleep
+        if(!IsDueStreamLimit())
+        {
+            if( !m_pScheduler3->IsPaused() )
+            {
+                m_ulSchedulerPausedTime = HX_GET_BETTERTICKCOUNT();
+                UINT32 ulCurrSchedRunTime = m_ulSchedulerPausedTime - m_ulSchedulerResumedTime;
+                m_ulTotalSchedRunTime += ulCurrSchedRunTime;
+                HXLOGL2( HXLOG_MDFA, "CHXAudioDevice[%p]::HighWaterMark PSave PauseScheduler RunTime:%lu TotRun:%lu", this, ulCurrSchedRunTime, m_ulTotalSchedRunTime);
+                m_pScheduler3->PauseScheduler();
+            }
+
+            m_bDisableOnTimeSyncTimer = TRUE;
+			m_bDevTimeNeeded = TRUE;
+
+            // Cancel the timer used for ontimesync reporting
+            if (IsActive())
+            {
+                HXLOGL3( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::Calling cancel ", this);
+                Cancel();
+            }
+        } // End of if(!IsDueStreamLimit())
+    } // End of if(m_bIsInPowerSave)
+
+}
+
+
+void CHXMDFAudioDevice::LowWaterMark()
+{
+    HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::LowWaterMark m_bIsInPowerSave:%d ", this, m_bIsInPowerSave);
+
+    if(m_bIsInPowerSave)
+    {
+        if( m_pScheduler3->IsPaused() )
+        {
+            m_ulSchedulerResumedTime = HX_GET_BETTERTICKCOUNT();
+            UINT32 ulCurrSchedSleepTime = m_ulSchedulerResumedTime - m_ulSchedulerPausedTime;
+            m_ulTotalSchedSleepTime += ulCurrSchedSleepTime;
+            HXLOGL2( HXLOG_MDFA, "CHXAudioDevice[%p]::LowWaterMark PSave ResumeScheduler PauseTime:%lu TotPause:%lu", this, ulCurrSchedSleepTime, m_ulTotalSchedSleepTime);
+
+            m_pScheduler3->ResumeScheduler();
+        }
+
+        //set timer for OntimeSync or unpause timer for ontimesync
+        m_bDisableOnTimeSyncTimer = FALSE;
+        m_bDevTimeNeeded = TRUE;
+        if( !IsActive())
+        {
+            m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+            HXLOGL3( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::LowWaterMark calling SetActive ", this);
+            DoSetTimer();
+        }
+    } // End of if(m_bIsInPowerSave)
+}
+
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 //
 // convenience methods
 //

--------------------------------------------------------------------------------------------------------------------


Index: mdfdevsound.h
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfdevsound.h,v
retrieving revision 1.17.4.2
diff -u -r1.17.4.2 mdfdevsound.h
--- mdfdevsound.h	4 May 2010 08:16:41 -0000	1.17.4.2
+++ mdfdevsound.h	31 Aug 2010 19:20:51 -0000
@@ -62,6 +62,10 @@
 #include "mdfdevconfig.h"
 #include "CHXAudioOutputConfigUtil.h"
 
+//***************************************************************//
+//For the power save mode
+class CHXPowerSaveAudDeviceObserver;
+//***************************************************************//
 class CHXMDFAudioDevice;
 class CHXMDFAudioDeviceObserver;
 class CHXMMFDevSound;
@@ -142,6 +146,13 @@
     
         // helper
         void SetAudioDeviceObserver(CHXMDFAudioDeviceObserver* p) {m_pDevObserver=p;};
+    //for power save
+        void SetPowerSaveConfig(CHXPowerSaveAudDeviceObserver* pPowSaveAudDevObserver, const UINT32& ulHighWaterMark, const UINT32& ulLowWaterMark);
+        void CheckForLWM();
+        void CheckForHWM();
+        void GetTotalUnPlayedDataInMs( UINT32& ulUnPlayedData);
+        void SetLastRecvdEncodedData(const UINT32& ulLastAudioWrite);
+        void SetAudioTimeOffset(UINT32 ulAudioTimeOffset) {m_ulAudioTimeOffset = ulAudioTimeOffset;}
         
     private:
         // constructor
@@ -206,6 +217,16 @@
         // status observer. only one in this implementation
         CHXMDFAudioDeviceObserver*     m_pDevObserver;
         
+    private:
+	
+        UINT32 m_ulHighWaterMark;
+        UINT32 m_ulLowWaterMark;
+        UINT32 m_ulLastEncodedWriteTime;
+        UINT32 m_ulLastDevWriteTime;
+        UINT32 m_ulAudioTimeOffset;
+        HXBOOL m_bDetectedHWM;
+        CHXPowerSaveAudDeviceObserver*     m_pPowSaveAudDevObserver;
+        
     // methods for FourCC            
     private:
 #ifdef _DEBUG_TEST_AUDIO_DEVICE_TAKEN_
@@ -231,4 +252,10 @@
         virtual void OnDeviceError(HX_RESULT hxr) = 0;
 };
 
+class CHXPowerSaveAudDeviceObserver
+{
+    public:
+        virtual void HighWaterMark() = 0;
+        virtual void LowWaterMark() = 0;
+};
 #endif


--------------------------------------------------------------------------------------------------------------------


Index: mdfdevsound.cpp
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfdevsound.cpp,v
retrieving revision 1.28.4.5
diff -u -r1.28.4.5 mdfdevsound.cpp
--- mdfdevsound.cpp	6 May 2010 03:34:26 -0000	1.28.4.5
+++ mdfdevsound.cpp	31 Aug 2010 19:37:50 -0000
@@ -150,6 +150,13 @@
 #ifdef _DEBUG_TEST_AUDIO_DEVICE_TAKEN_
     		,m_lErrCnt(1)
 #endif 
+            , m_ulHighWaterMark(0)
+            , m_ulLowWaterMark(0)
+            , m_ulLastEncodedWriteTime(0)
+            , m_ulLastDevWriteTime(0)
+            , m_ulAudioTimeOffset(0)
+            , m_pPowSaveAudDevObserver(NULL)
+            ,m_bDetectedHWM(FALSE)
 {
     HX_ASSERT(pFrameList);
     HX_ASSERT(pFormat);
@@ -337,8 +344,11 @@
     m_ulSamplesPlayedOffset = GetValidSamplesPlayed(); //BySamplesPlayed
 
 	//samples played before taken and samples written reset to zero
-	m_ulSamplesPlayedBeforeTaken = 0;
-
+    m_ulSamplesPlayedBeforeTaken = 0;
+    m_ulLastDevWriteTime = 0;
+    m_ulLastEncodedWriteTime = 0;
+    m_ulAudioTimeOffset = 0;
+    m_bDetectedHWM = FALSE;
     
     HXLOGL2(HXLOG_MDFA, "---devsnd:reset .. before flush %lu", (UINT32)m_ulSamplesPlayedOffset);
 
@@ -351,8 +361,10 @@
     {
         HX_ASSERT(m_pAddedDevSoundCI);
 		m_devStatus = DevPaused;
-        lError = m_pAddedDevSoundCI->PauseAndFlush();
-
+        if(m_pAddedDevSoundCI != NULL)
+        {
+            lError = m_pAddedDevSoundCI->PauseAndFlush();
+        }
         if (lError!=KErrNone) return HXR_FAIL;
 
     #if defined(HELIX_FEATURE_LOGLEVEL_4)
@@ -412,7 +424,7 @@
 {
     PRINTCURRENTSTATE("---devsnd:PLAY <");
 
-    if (m_devStatus == DevPaused)
+    if ((m_devStatus == DevPaused) || (m_devStatus == DevInitialized) )
     {   //resume
         if (m_pDevSoundBuffer)  // we have the dev buffer
         {
@@ -898,7 +910,6 @@
     }
 
     // -- Start playback loop --
-    StartPlayback();
 
     HXLOGL4(HXLOG_MDFA, "---devsnd:InitComp > %d", aError);
 }
@@ -948,7 +959,7 @@
     else
     {
         HXMDFAudioData* pAudioData = (HXMDFAudioData*)m_pDataList->GetHead();
-        UINT32 ulDataTime = pAudioData->m_ulAudioTime;
+        m_ulLastDevWriteTime = pAudioData->m_ulAudioTime - m_ulAudioTimeOffset;
 
         HX_RESULT retErr = HXR_OK;
         if (pAudioData->m_bMissing || pAudioData->m_bConcealed)
@@ -1017,6 +1028,7 @@
             m_ulFramesPlayedLastRound = 1;
             m_pDevSoundBuffer = NULL;
             m_pDevSound->PlayData();
+            CheckForLWM(); 
        }
         else
         {
@@ -1144,6 +1156,115 @@
 }
 
 
+//
+//  CMDFDevSound::SetPowerSaveConfig
+// 
+void CMDFDevSound::SetPowerSaveConfig(CHXPowerSaveAudDeviceObserver* pPowSaveAudDevObserver
+											, const UINT32& ulHighWaterMark
+											, const UINT32& ulLowWaterMark)
+{
+    HXLOGL2(HXLOG_MDFA,"CMDFDevSound::SetPowerSaveConfig m_ulHighWaterMark =%d, m_ulLowWaterMark =%d", m_ulHighWaterMark, m_ulLowWaterMark);
+
+    m_ulHighWaterMark = ulHighWaterMark;
+    m_ulLowWaterMark = ulLowWaterMark;
+    m_pPowSaveAudDevObserver = pPowSaveAudDevObserver;
+}
+
+//
+//  CMDFDevSound::SetLastRecvdEncodedData
+//  Timestamp of last encoded frame in Q
+// 
+void CMDFDevSound::SetLastRecvdEncodedData(const UINT32& ulLastAudioWrite)
+{
+    m_ulLastEncodedWriteTime = ulLastAudioWrite;
+    CheckForHWM();
+    HXLOGL4(HXLOG_CORE,"mdfdev:Write .. Obs:%p last buf time:%lu", m_pPowSaveAudDevObserver, ulLastAudioWrite);
+}
+
+//
+//  CMDFDevSound::CheckForHWM
+//  Checks if Q has reached high water mark
+//  and report to the observer
+// 
+void CMDFDevSound::CheckForHWM()
+{
+    //  Check if we have enough data to report
+    //  high water mark
+
+    //  We are not checking for m_bDetectedHWM as this call
+    //  should not happen when it is TRUE
+    //
+    if(m_pPowSaveAudDevObserver != NULL)
+    {
+        UINT32 ulTimeLeft = 0;
+        UINT32 ulTimeInDev = 0;
+
+        // First caluclate the data in Q
+        ulTimeLeft = m_ulLastEncodedWriteTime - m_ulLastDevWriteTime;
+
+        //  We use the last updated samples played
+        //  Inaccuracy could be upto 30msec as it is updated from during
+        //  the ontimesync reporting
+        ulTimeInDev = (m_ulLastValidSamplesPlayed - m_ulSamplesPlayedOffset)  * 1000 / m_pAudioFormat->m_ulSamplesPerSec;
+        ulTimeInDev = m_ulLastDevWriteTime - ulTimeInDev;
+
+        ulTimeLeft += ulTimeInDev;
+
+        HXLOGL4(HXLOG_MDFA,"mdfdev:CheckForHWM .. DataInQ:%lu m_ulLastDevWriteTime:%lu",ulTimeLeft, m_ulLastDevWriteTime);
+        
+        if(ulTimeLeft > m_ulHighWaterMark)
+        {
+            m_pPowSaveAudDevObserver->HighWaterMark();
+            HXLOGL4(HXLOG_MDFA,"devsnd:CheckForHWM .. m_bDetectedHWM=%d", m_bDetectedHWM);
+            m_bDetectedHWM = TRUE;
+        }
+    } // End of if(m_pPowSaveAudDevObserver != NULL)
+}
+
+//
+//  CMDFDevSound::CheckForLWM
+//  Checks if Q is below low water mark
+//  and reports to the observer
+// 
+void CMDFDevSound::CheckForLWM()
+{
+    HXLOGL4(HXLOG_MDFA,"devsnd:CheckForLWM .. m_bDetectedHWM=%d", m_bDetectedHWM);
+    if( (m_pPowSaveAudDevObserver != NULL) && (m_bDetectedHWM) )
+    {
+        UINT32 ulDataInQ = m_ulLastEncodedWriteTime - m_ulLastDevWriteTime;
+
+        HXLOGL4(HXLOG_MDFA,"devsnd:CheckForLWM .. ulDataInQ=%lu", ulDataInQ);
+        // We first check, if data in Q is nearing LWM. 
+        // This will reduce the number of samplesplayed calculation
+        if(ulDataInQ < m_ulLowWaterMark)
+        {
+            UINT32 ulTotalUnplayedDataInMs = 0;
+            // Calculate accurate unplayed samples time
+            GetTotalUnPlayedDataInMs(ulTotalUnplayedDataInMs);
+            HXLOGL4(HXLOG_MDFA,"devsnd:CheckForLWM .. Pending=%lu Obs:%p", ulTotalUnplayedDataInMs, m_pPowSaveAudDevObserver);
+            if(ulTotalUnplayedDataInMs <= m_ulLowWaterMark)
+            {
+                m_pPowSaveAudDevObserver->LowWaterMark();
+                m_bDetectedHWM = FALSE;
+            }
+        } // End of if(ulDataInQ < m_ulLowWaterMark)
+
+    } // End of if( (m_pPowSaveAudDevObserver != NULL) && (!m_bDetectedHWM) )
+}
+
+//
+//  CMDFDevSound::GetTotalUnPlayedDataInMs
+//  Returns the amount of unplayed 
+//  data(including data sent to devsound)
+// 
+void CMDFDevSound::GetTotalUnPlayedDataInMs( UINT32& ulUnPlayedData)
+{
+    UINT32 ulPlayTime = 0;
+    GetCurrentPlayTime(ulPlayTime);
+    ulUnPlayedData = m_ulLastEncodedWriteTime - ulPlayTime;
+}
+
+
 //--------------------
 //  Static Methods
 //--------------------


-------------------------------------------------------------------------------------------------------------------


Index: hxaudply.h
===================================================================
RCS file: /cvsroot/client/audiosvc/pub/hxaudply.h,v
retrieving revision 1.21.78.1
diff -u -r1.21.78.1 hxaudply.h
--- hxaudply.h	18 Sep 2009 04:45:12 -0000	1.21.78.1
+++ hxaudply.h	31 Aug 2010 16:40:29 -0000
@@ -55,6 +55,9 @@
 #include "hxplayvelocity.h"
 #include "hxslist.h"
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxTimelineLimit.h"
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
 // forward decls
 struct IHXAudioPlayerResponse;
 struct IHXAudioStream;
@@ -65,10 +68,6 @@
 struct IHXPreferences;
 struct IHXAudioCrossFade;
 
-#if defined(HELIX_FEATURE_POWER_SAVE)
-_INTERFACE IHXPowerSave;
-#endif // HELIX_FEATURE_POWER_SAVE
-
 typedef struct _HXAudioFormat HXAudioFormat;
 
 class CHXAudioSession;
@@ -99,6 +98,7 @@
 #endif 
 #ifdef HELIX_FEATURE_POWER_SAVE
 		      public IHXPowerSave,
+			  public IHXTimeLineLimit,
 #endif
 		      public IHXAudioCrossFade,
 		      public IHXCallback,
@@ -163,7 +163,8 @@
     
 #if defined(HELIX_FEATURE_POWER_SAVE)
     HXBOOL          m_bInPowerSave;         // Player in power save mode
-    IHXPowerSave*   m_pRendererPowerSave;
+    IHXPowerSave*   m_pPowerSave;
+    UINT32          m_ulLimitInMs;
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
   protected:
@@ -227,15 +228,22 @@
         
 #endif        
 
+protected:
+        void ApplyTimeLineLimit();
+public:	
 #if defined(HELIX_FEATURE_POWER_SAVE)
-    HX_RESULT RetrieveRendererPowerSave();
+	/*Implement IHXTimeLineLimit*/
+    STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs );
+    STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs );
+    STDMETHOD(ResetLimit) (THIS);
+    HX_RESULT RetrievePowerSave();
     /* IHXPowerSave methods */
     STDMETHOD_(HX_RESULT,StartPowerSave)                  ( THIS );
     STDMETHOD_(HX_RESULT,EndPowerSave)                    ( THIS );
     STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
     STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
     STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
-    STDMETHOD_(ULONG32,SetWakeUpInterval)      ( THIS_ ULONG32 /*IN*/ ulWakeUpInterval );
+    STDMETHOD(SetWakeUpInterval)      ( THIS_ ULONG32 ulWakeUpInterval );
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
 ---------------------------------------------------------------------------------------------------------------
 
 Index: hxaudply.cpp
 ===================================================================
 RCS file: /cvsroot/client/audiosvc/hxaudply.cpp,v
 retrieving revision 1.58.12.1
 diff -u -r1.58.12.1 hxaudply.cpp
 --- hxaudply.cpp	18 Sep 2009 04:45:11 -0000	1.58.12.1
 +++ hxaudply.cpp	31 Aug 2010 16:59:36 -0000
 @@ -152,8 +152,9 @@
  ,       m_pLastMappingStream(NULL)
  ,       m_bNewMapStarting(TRUE)    
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -,	    m_bInPowerSave(FALSE)
 -,       m_pRendererPowerSave(NULL)
 +,       m_bInPowerSave(FALSE)
 +,       m_pPowerSave(NULL)
 +,       m_ulLimitInMs(0)
  #endif /*HELIX_FEATURE_POWER_SAVE*/
  {
  #ifdef HELIX_FEATURE_VOLUME
 @@ -253,13 +254,13 @@
      // Delete the inactive clock source queue
      HX_DELETE(m_pInactiveClockSourceQueue);
  
 -    
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -        if(m_pRendererPowerSave)
 -        {
 -            HX_RELEASE(m_pRendererPowerSave);
 -        }
 +    if(m_pPowerSave)
 +    {
 +    	HX_RELEASE(m_pPowerSave);
 +    }
  #endif    
 +
  }
  
  /////////////////////////////////////////////////////////////////////////
 @@ -287,6 +288,9 @@
              , { GET_IIDHANDLE(IID_IHXPlaybackVelocity), (IHXPlaybackVelocity*)this }
  #endif /* #if defined(HELIX_FEATURE_PLAYBACK_VELOCITY) */
              , { GET_IIDHANDLE(IID_IHXClockSourceManager), (IHXClockSourceManager*) this }
 +#if defined(HELIX_FEATURE_POWER_SAVE)
 +            ,{ GET_IIDHANDLE(IID_IHXTimeLineLimit), (IHXTimeLineLimit*) this}
 +#endif
          };
  
      HX_RESULT res = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
 @@ -1482,6 +1486,7 @@
  	{
              theErr = m_Owner->Resume(this, bSessionRewindNeededForStream);
  	}
 +        ApplyTimeLineLimit();
      }
      else
      {
 @@ -1580,6 +1585,9 @@
          StopFakeTimeline();
      }
  
 +#if defined(HELIX_FEATURE_POWER_SAVE)
 +    EndPowerSave();
 +#endif    
      ResetPlayer();
  
      return HXR_OK;
 @@ -3020,41 +3028,64 @@
  }
  
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -HX_RESULT CHXAudioPlayer::RetrieveRendererPowerSave() {
 -    if (m_pRendererPowerSave != NULL)
 +HX_RESULT CHXAudioPlayer::RetrievePowerSave() 
 +{
 +    HX_RESULT retVal = HXR_FAIL;
 +	
 +    if (m_pPowerSave)
      {
 -        return HXR_OK;
 +	    retVal = HXR_OK;
      }
 -
 -    if (m_pActiveClockSource != NULL &&
 -        (m_pActiveClockSource->QueryInterface(IID_IHXPowerSave, (void**) &m_pRendererPowerSave) == HXR_OK))
 +    else
      {
 -        return HXR_OK;
 +        if (m_pActiveClockSource != NULL )
 +        {    
 +	        if (m_pActiveClockSource->QueryInterface(IID_IHXPowerSave, (void**) &m_pPowerSave) == HXR_OK)
 +            {
 +                retVal = HXR_OK;
 +            }
 +        }
 +        else 
 +        {
 +            if(m_Owner)
 +            { //device powersave
 +	              IHXAudioDevice * pAudioDev = NULL;
 +	              m_Owner->QueryInterface(IID_IHXAudioDevice, (void**) &pAudioDev);
 +	            
 +                if(pAudioDev)
 +                {
 +                    if (pAudioDev->QueryInterface(IID_IHXPowerSave, (void**) &m_pPowerSave) == HXR_OK)
 +                    {
 +                        retVal = HXR_OK;
 +                    }
 +                    HX_RELEASE(pAudioDev);
 +                }
 +            }
 +        }
      }
 -
 -    m_pRendererPowerSave = NULL;
 -    return HXR_FAIL;
 +	
 +    return retVal;
  }
  
  /* IHXPowerSave methods */
  STDMETHODIMP CHXAudioPlayer::StartPowerSave (void)
  {
      HX_RESULT theErr = HXR_FAIL;
 +	
      if (IsInPowerSave())
      {
 -        return HXR_FAIL;
 +        theErr =  HXR_ALREADY_INITIALIZED;
      }
 -
 -    if (!CanStartPowerSave())
 -    {
 -        return HXR_FAIL;
 -    }
 -
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    else
      {
 -        theErr = m_pRendererPowerSave->StartPowerSave();
 +        if (CanStartPowerSave())
 +        {
 +            if (RetrievePowerSave() == HXR_OK)
 +            {
 +                theErr = m_pPowerSave->StartPowerSave();
 +            }     
 +        }
      }
 -
      if (theErr == HXR_OK)
      {
          m_bInPowerSave = TRUE;
 @@ -3066,21 +3097,20 @@
  STDMETHODIMP CHXAudioPlayer::EndPowerSave (void)
  {
      HX_RESULT theErr = HXR_FAIL;
 -    if (!IsInPowerSave())
 -    {
 -        return HXR_FAIL;
 -    }
 -
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +	
 +    if (IsInPowerSave())
      {
 -        theErr = m_pRendererPowerSave->EndPowerSave();
 +        if (RetrievePowerSave() == HXR_OK)
 +        {
 +	        theErr = m_pPowerSave->EndPowerSave();
 +        }
      }
 -
      if (theErr == HXR_OK)
      {
          m_bInPowerSave = FALSE;
 -        m_pRendererPowerSave = NULL;
      }
 +    HX_RELEASE(m_pPowerSave);
 +
      return theErr;
  }
  
 @@ -3091,33 +3121,106 @@
  
  STDMETHODIMP_(HXBOOL) CHXAudioPlayer::CanStartPowerSave (void)
  {
 -    if (m_bHasStreams)
 -    {
 -        return FALSE;
 -    }
 +    HXBOOL retVal = FALSE;
  
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    if (RetrievePowerSave() == HXR_OK)
      {
 -        return m_pRendererPowerSave->CanStartPowerSave();
 +        retVal = m_pPowerSave->CanStartPowerSave();
      }
  
 -    return FALSE;
 +    return retVal;
  }
  
  STDMETHODIMP_(ULONG32) CHXAudioPlayer::GetWakeUpInterval (void)
  {
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    if (RetrievePowerSave() == HXR_OK)
      {
 -        return m_pRendererPowerSave->GetWakeUpInterval();
 +        return m_pPowerSave->GetWakeUpInterval();
      }
 +    return 0;
 +}
 +
 +STDMETHODIMP CHXAudioPlayer::SetWakeUpInterval (ULONG32  ulWakeUpInterval)
 +{
 +    HX_RESULT retVal = HXR_FAIL;
 +	if (RetrievePowerSave() == HXR_OK)
 +    {
 +        retVal = m_pPowerSave->SetWakeUpInterval(ulWakeUpInterval);
 +    }
 +	
 +	return retVal;
 +}
 +#endif
 +void CHXAudioPlayer::ApplyTimeLineLimit()
 +{
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +    UINT32 ulLimitInMs = 0;
 +
 +    ulLimitInMs = m_ulLimitInMs - m_ulAPstartTime + m_ulADresumeTime;
 +    HXLOGL2(HXLOG_ADEV, "CHXAudioPlayer[%p]::ApplyTimeLineLimit ulLimitInMs:%lu ", this, ulLimitInMs);
 +    
 +    if(m_Owner)
 +    { // Set audio session timelinelimit
 +        IHXTimeLineLimit* pTimeLineLimit = NULL;
 +        m_Owner->QueryInterface(IID_IHXTimeLineLimit, (void**) & pTimeLineLimit);
 +        if(pTimeLineLimit != NULL)
 +        {
 +            UINT32 ulDevLimitInMs = pTimeLineLimit->SetLimit(ulLimitInMs );
 +            HX_RELEASE(pTimeLineLimit);
 +        }
 +    } // End of if(m_Owner)
 +#endif
 +}
 +
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +STDMETHODIMP 
 +CHXAudioPlayer::SetLimit (UINT32 ulLimitInMs )
 +{
 +    HXLOGL2(HXLOG_ADEV, "CHXAudioPlayer[%p]::SetLimit ulLimitInMs:%lu ", this, ulLimitInMs);
 +    //  Store the limit (Presentation duration)
 +    //  Should be applied on audio session during resume
 +    //  after adjusting the start time
 +    m_ulLimitInMs = ulLimitInMs;
 +
 +    return HXR_OK;
  }
  
 -STDMETHODIMP_(ULONG32) CHXAudioPlayer::SetWakeUpInterval (ULONG32 /*IN*/ ulWakeUpInterval)
 +STDMETHODIMP 
 +CHXAudioPlayer::GetLimit (UINT32 &ulLimitInMs )
  {
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    HX_RESULT retVal = HXR_FAIL;
 +
 +    HXLOGL2(HXLOG_ADEV, "CHXAudioPlayer[%p]::GetLimit m_ulLimitInMs:%lu m_ulAPstartTime:%lu", this, m_ulLimitInMs, m_ulAPstartTime);
 +
 +    if(m_ulLimitInMs > 0)
      {
 -        return m_pRendererPowerSave->SetWakeUpInterval(ulWakeUpInterval);
 +        ulLimitInMs = m_ulLimitInMs - m_ulAPstartTime + m_ulADresumeTime;
 +        retVal = HXR_OK;
      }
 +
 +    return retVal;
  }
  
 +STDMETHODIMP 
 +CHXAudioPlayer::ResetLimit()
 +{
 +    HX_RESULT retVal = HXR_OK;
 +
 +    m_ulLimitInMs = 0;
 +
 +    if(m_Owner)
 +    {
 +        IHXTimeLineLimit* pTimeLineLimit = NULL;
 +        m_Owner->QueryInterface(IID_IHXTimeLineLimit, (void**) & pTimeLineLimit);
 +        if(pTimeLineLimit != NULL)
 +        {
 +            retVal = pTimeLineLimit->ResetLimit();
 +            HX_RELEASE(pTimeLineLimit);
 +        }
 +    } // End of if(m_Owner)
 +
 +    HXLOGL3(HXLOG_CORE, "CHXAudioPlayer[%p]::ResetLimit retVal:%x ", this, retVal);
 +    return retVal;
 +
 +}
  #endif /*HELIX_FEATURE_POWER_SAVE*/

 
---------------------------------------------------------------------------------------------------------------

Index: hxaudses.h
===================================================================
RCS file: /cvsroot/client/audiosvc/pub/hxaudses.h,v
retrieving revision 1.33.8.1
diff -u -r1.33.8.1 hxaudses.h
--- hxaudses.h	18 Sep 2009 04:45:12 -0000	1.33.8.1
+++ hxaudses.h	31 Aug 2010 17:04:08 -0000
@@ -58,6 +58,10 @@
 #include 
 #endif
 #include "hxcore.h"
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxTimelineLimit.h"
+#include  "hxPowerSave.h"
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
 //  IHXTimelineWatcher defines.
 #  define TLW_PAUSE    1
 #  define TLW_RESUME   2
@@ -116,10 +120,6 @@
 struct IHXAudioHook;
 struct IHXInterruptState;
 
-#if defined(HELIX_FEATURE_POWER_SAVE)
-_INTERFACE IHXPowerSave;
-#endif // HELIX_FEATURE_POWER_SAVE
-
 typedef struct _HXAudioFormat HXAudioFormat;
 class CHXAudioPlayer;
 
@@ -151,7 +151,8 @@
     public IHXVolumeAdviseSink,
 #endif                          
 #ifdef HELIX_FEATURE_POWER_SAVE
-		      public IHXPowerSave,
+    public IHXPowerSave,
+    public IHXTimeLineLimit,
 #endif
     public IHXCallback,
     public IHXAudioResamplerManager,
@@ -328,7 +329,20 @@
                                          HXBOOL&     /*OUT*/    bChanged
                                          );
 
+protected:
+    void ApplyPushdownLimit(UINT16& ulPushdown);
+    void CreateAudDevInterfaces(IHXAudioDevice* pAudioDev);
+    void ReleaseAudDeviceInterfaces();
 #if defined(HELIX_FEATURE_POWER_SAVE)
+	HX_RESULT ComputePowerSaveModePushDown();
+	UINT32 UpdateLimit();
+    
+public:
+
+	/*Implement IHXTimeLineLimit*/
+	STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs );
+	STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs );
+	STDMETHOD(ResetLimit) (THIS);
     /* 
      * IHXPowerSave methods
      */
@@ -337,9 +351,9 @@
     STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
     STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
     STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
-    STDMETHOD_(ULONG32,SetWakeUpInterval)      ( THIS_ ULONG32 /*IN*/ ulWakeUpInterval );
+	STDMETHOD(SetWakeUpInterval  ) (THIS_ ULONG32 ulWakeUpInterval );
 #endif /*HELIX_FEATURE_POWER_SAVE*/
-
+public:
 
     /*
      *  IHXAudioDeviceManager2 methods
@@ -657,6 +671,11 @@
     HXBOOL                  m_bMute;                // the mute state
 #if defined(HELIX_FEATURE_POWER_SAVE)
     HXBOOL                  m_bInPowerSave;         // Player in power save mode
+    UINT32                  m_ulWakeUpInterval;
+    IHXPowerSave*           m_pPowerSave;  
+    IHXTimeLineLimit*       m_pTimeLineLimit;
+    UINT32                  m_ulLimitInMs; 
+    ULONG32                 m_ulPrePowerSavePushdown;
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
     /*

------------------------------------------------------------------------------------------------------------------

Index: hxaudses.cpp
===================================================================
RCS file: /cvsroot/client/audiosvc/hxaudses.cpp,v
retrieving revision 1.84.2.1.2.1
diff -u -r1.84.2.1.2.1 hxaudses.cpp
--- hxaudses.cpp	12 Jan 2010 08:37:46 -0000	1.84.2.1.2.1
+++ hxaudses.cpp	31 Aug 2010 17:19:08 -0000
@@ -233,6 +233,11 @@
     , m_bMute(FALSE)
 #if defined(HELIX_FEATURE_POWER_SAVE)
     , m_bInPowerSave(FALSE)
+    , m_ulWakeUpInterval(0)
+    , m_pPowerSave(NULL)
+    , m_pTimeLineLimit(NULL)
+    , m_ulLimitInMs (0)
+    , m_ulPrePowerSavePushdown(0)
 #endif /*HELIX_FEATURE_POWER_SAVE*/
     , m_dBufEndTime((double) 0.)
     , m_bDisableWrite(FALSE)
@@ -470,9 +475,22 @@
 #endif            
             { GET_IIDHANDLE(IID_IHXAudioPushdown2),      (IHXAudioPushdown2*)this       },
             { GET_IIDHANDLE(IID_IHXAudioDeviceHookManager), (IHXAudioDeviceHookManager*)this},
+#ifdef HELIX_FEATURE_POWER_SAVE
+            { GET_IIDHANDLE(IID_IHXTimeLineLimit), (IHXTimeLineLimit*)this },
+            { GET_IIDHANDLE(IID_IHXPowerSave), (IHXPowerSave*)this },
+#endif /*HELIX_FEATURE_POWER_SAVE*/
         };
 
-    return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
+    HX_RESULT retval = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
+
+#ifdef HELIX_FEATURE_POWER_SAVE
+    if (retval != HXR_OK && m_pCurrentAudioDev)
+    {
+        retval = m_pCurrentAudioDev->QueryInterface(riid, ppvObj);
+    }
+#endif
+
+    return retval; 
 }
 
 /////////////////////////////////////////////////////////////////////////
@@ -1243,6 +1261,7 @@
  */
 HX_RESULT CHXAudioSession::PlayAudio(UINT16 uNumBlocks)
 {
+    ApplyPushdownLimit(uNumBlocks);
     HXLOGL4(HXLOG_ADEV, "CHXAudioSession[%p]::PlayAudio(): %u blocks", this, uNumBlocks);
 
     HX_RESULT theErr = HXR_OK;
@@ -2073,6 +2092,7 @@
 
             m_pCurrentAudioDev = (IHXAudioDevice*) pAudioDev;
 
+            CreateAudDevInterfaces(pAudioDev);
             HXLOGL3(HXLOG_ADEV, "CHXAudioSession[%p]::CreateAudioDevice(): created [%p]", this, m_pCurrentAudioDev);
         }
         else
@@ -2097,6 +2117,7 @@
     _NotifyTimelineWatchers( TLW_CLOSE );
     HX_RELEASE(m_pCurrentAudioDev);
 
+    ReleaseAudDeviceInterfaces();
     m_bToBeReOpened = FALSE;
     if (m_pDeviceCallback && m_pDeviceCallback->PendingID())
     {
@@ -2633,11 +2654,13 @@
         m_pCurrentAudioDev->Close(TRUE);
         _NotifyTimelineWatchers( TLW_CLOSE );
         HX_RELEASE(m_pCurrentAudioDev);
+        ReleaseAudDeviceInterfaces();
     }
 
     m_pCurrentAudioDev = pAudioDevice;
     m_pCurrentAudioDev->AddRef();
 
+    CreateAudDevInterfaces(m_pCurrentAudioDev);
     m_pReplacedAudioDev = pAudioDevice;
     m_pReplacedAudioDev->AddRef();
 
@@ -2712,6 +2735,7 @@
         HX_RELEASE(m_pCurrentAudioDev);
     }
 
+    ReleaseAudDeviceInterfaces();
     HX_RELEASE(m_pReplacedAudioDev);
     m_bReplacedDev = FALSE;
 
@@ -4502,32 +4526,244 @@
     }
 }
 
+//
+//  CHXAudioSession::ApplyPushdownLimit
+//  Limits the pushdown value based on
+//  power save cfg
+//
+void CHXAudioSession::ApplyPushdownLimit(UINT16& ulPushdown)
+{
+    //  Reason to limit is to avoid the mixer from producing
+    //  dummy silence data at the end of the playback
+#ifdef HELIX_FEATURE_POWER_SAVE
+    if(m_bInPowerSave && m_ulLimitInMs > 0)
+    {
+        if( m_ulLimitInMs < ((m_ulBlocksWritten + ulPushdown) * m_dGranularity) )
+        {
+            // ulPushdown needs to update
+            ulPushdown = ((m_ulLimitInMs / m_dGranularity) - m_ulBlocksWritten);
+            // Adding a block to cover roundoff errors.
+            ulPushdown++;
+
+        }
+    } // End of if(m_bInPowerSave && m_ulLimitInMs > 0)
+#endif // End of #ifdef HELIX_FEATURE_POWER_SAVE
+}
+
+//
+//  CHXAudioSession::CreateAudDevInterfaces
+//  To create interfaces from audio device
+//
+void CHXAudioSession::CreateAudDevInterfaces(IHXAudioDevice* pAudioDev)
+{
+    ReleaseAudDeviceInterfaces();
+#ifdef HELIX_FEATURE_POWER_SAVE
+    if(pAudioDev != NULL)
+    {
+        pAudioDev->QueryInterface(IID_IHXPowerSave, (void**) &m_pPowerSave);
+        pAudioDev->QueryInterface(IID_IHXTimeLineLimit, (void**) &m_pTimeLineLimit);
+
+        if (m_pPowerSave==0 || m_pTimeLineLimit==0)
+        {
+            HXLOGL2(HXLOG_ADEV, "CHXAudioSession::CreateAudDevInterfaces:query m_pPowerSave or m_pTimeLineLimit return 0");
+        }
+
+    }
+#endif
+}
+
+//
+//  CHXAudioSession::ReleaseAudDeviceInterfaces
+//  releases interfaces created from audio device
+//
+void CHXAudioSession::ReleaseAudDeviceInterfaces()
+{
+#ifdef HELIX_FEATURE_POWER_SAVE
+    HX_RELEASE(m_pPowerSave);
+    HX_RELEASE(m_pTimeLineLimit);
+#endif
+}
+
+
 #if defined(HELIX_FEATURE_POWER_SAVE)
-/* IHXPowerSave methods */
-STDMETHODIMP_(HX_RESULT) CHXAudioSession::StartPowerSave (void)
+//
+//  CHXAudioSession::UpdateLimit
+//  Queries the limit from all players
+//  and uses the min for device and max for
+//  pushdown limit
+//
+UINT32 CHXAudioSession::UpdateLimit()
 {
-    HX_RESULT theErr = HXR_FAIL;
-    if (IsInPowerSave())
+    UINT32 ulLowestLimitInMs = MAX_UINT32;
+    UINT32 ulHighestLimitInMs = 0;
+    HX_RESULT rv = HXR_OK;
+
+    HXLOGL3(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): m_pPlayerList = %p", this, m_pPlayerList);
+    if(m_pPlayerList && m_pPlayerList->GetCount() > 0)
     {
-        return HXR_FAIL;
+
+        CHXAudioPlayer* pPlayer = NULL;
+        CHXSimpleList::Iterator lIter;
+        for (lIter = m_pPlayerList->Begin(); lIter != m_pPlayerList->End(); ++lIter)
+        {
+            IHXTimeLineLimit* pTimeLimit = NULL;
+            pPlayer = (CHXAudioPlayer*) (*lIter);
+            pPlayer->QueryInterface(IID_IHXTimeLineLimit, (void**) &pTimeLimit);
+            if(pTimeLimit)
+            {
+                UINT32 ulLimit = 0;
+                rv = pTimeLimit->GetLimit(ulLimit);
+                HXLOGL2(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): pTimeLimit:%p ulLimit:%lu", this, pTimeLimit, ulLimit);
+                HX_RELEASE(pTimeLimit);
+                if( (rv == HXR_NO_DATA) || (ulLimit == 0) )
+                {
+                    // Player is not interested in applying limit
+                    // break out
+                    ulLowestLimitInMs = 0;
+                    ulHighestLimitInMs = 0;
+                    break;
+                }
+                else
+                {
+                    if(ulLimit < ulLowestLimitInMs)
+                    {
+                        ulLowestLimitInMs = ulLimit;
+                    }
+
+                    if(ulLimit > ulHighestLimitInMs)
+                    {
+                        ulHighestLimitInMs = ulLimit;
+                    }
+                }
+            }
+            else
+            {
+                // One of the player is not interested in applying limit
+                // break out
+                ulLowestLimitInMs = 0;
+                ulHighestLimitInMs = 0;
+                HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): IHXTimeLineLimit NOT SUPPOPRTED", this);
+                break;
+            }
+
+        } // End of for (lIter = m_pPlayerList->Begin(); lIter != m_pPlayerList->End(); ++lIter)
+
+
+    } // End of if(m_pPlayerList && m_pPlayerList->GetCount() > 0)
+
+    HXLOGL2(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): Hi:%lu Lo:%lu", this, ulHighestLimitInMs, ulLowestLimitInMs);
+    if( (ulHighestLimitInMs != 0) && (ulLowestLimitInMs != 0) )
+    {
+        // highest value is used for max pushdown calculation
+        // Typically this is the duration of the playback
+        // start time is already adjusted on this limit
+        m_ulLimitInMs = ulHighestLimitInMs;
+
+        //set dev from audply
+        if(m_pTimeLineLimit != NULL)
+        {
+            // Lowest is set on the device
+            m_pTimeLineLimit->SetLimit(ulLowestLimitInMs);
+        }
+    } // End of if( (ulHighestLimitInMs != 0) && (ulLowestLimitInMs != 0) )
+    return ulLowestLimitInMs;
+}
+
+HX_RESULT CHXAudioSession::ComputePowerSaveModePushDown()
+{
+    HX_RESULT retVal = HXR_OK;
+    if(m_ulWakeUpInterval != 0)
+    {
+        retVal = SetAudioPushdown(m_ulWakeUpInterval);
     }
+	return retVal;
+}
+STDMETHODIMP CHXAudioSession::SetLimit (UINT32 ulLimitInMs )
+{
+    UINT32 retVal = 0;
+    m_pMutex->Lock();
 
-    if (!CanStartPowerSave())
+    //  ulLimitInMs is ignored
+    //  limit values are queried from all audio players
+    //  this call is used for getting limits from
+    //  all audio players
+
+    if(m_bInPowerSave)
     {
-        return HXR_FAIL;
+        retVal = UpdateLimit();
+        HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::SetLimit(): m_ulLimitInMs[%lu] ", this, m_ulLimitInMs);
     }
 
+    m_pMutex->Unlock();
 
-    if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+    return retVal;
+}
+
+STDMETHODIMP CHXAudioSession::GetLimit (UINT32 &ulLimitInMs )
+{
+    HX_RESULT retVal = HXR_FAIL;
+
+    m_pMutex->Lock();
+
+    if(m_ulLimitInMs != 0)
     {
-        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
-        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        theErr = pPlayer->StartPowerSave();
+        ulLimitInMs = m_ulLimitInMs;
+        retVal = HXR_OK;
     }
 
-    if (theErr == HXR_OK)
+    HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::GetLimit(): retVal = %x ulLimitInMs[%lu] ", this, ulLimitInMs);
+
+    m_pMutex->Unlock();
+
+    return retVal;
+}
+
+STDMETHODIMP CHXAudioSession::ResetLimit ()
+{
+	m_pMutex->Lock();
+
+	m_ulLimitInMs = 0;
+
+	if(m_pTimeLineLimit)
+	{
+		m_pTimeLineLimit->ResetLimit();
+	}
+
+	HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::ResetLimit() ", this);
+
+	m_pMutex->Unlock();
+
+	return HXR_OK;
+}
+/* IHXPowerSave methods */
+STDMETHODIMP_(HX_RESULT) CHXAudioSession::StartPowerSave (void)
+{
+    HXLOGL2(HXLOG_ADEV, "CHXAudioSession[%p]::StartPowerSave() ");
+    HX_RESULT theErr = HXR_FAIL;
+	
+    if (IsInPowerSave())
     {
-        m_bInPowerSave = TRUE;
+        theErr =  HXR_ALREADY_INITIALIZED;
+    }
+    else
+    {
+        if (CanStartPowerSave())
+        {
+            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+            CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+            if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+            {
+                theErr = pPlayer->StartPowerSave();
+
+                if (theErr == HXR_OK)
+                {
+                    m_bInPowerSave = TRUE;
+                    m_ulWakeUpInterval = pPlayer->GetWakeUpInterval();
+                    m_ulPrePowerSavePushdown = m_ulTargetPushdown;
+                    ComputePowerSaveModePushDown();
+                }
+            }
+        }
     }
 
     return theErr;
@@ -4535,18 +4771,22 @@
 
 STDMETHODIMP_(HX_RESULT) CHXAudioSession::EndPowerSave (void)
 {
+    HXLOGL2(HXLOG_ADEV, "CHXAudioSession[%p]::EndPowerSave() ");
     HX_RESULT theErr = HXR_FAIL;
-    if (!IsInPowerSave())
+	
+    if (IsInPowerSave())
     {
-        return HXR_FAIL;
+        if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+        {
+            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+            CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+            theErr = pPlayer->EndPowerSave();
+            UINT32 ulMinimumPushdown = (m_ulMinimumStartupPushdownGetCount() == 1)
-    {
-        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
-        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        theErr = pPlayer->EndPowerSave();
-    }
 
     if (theErr == HXR_OK)
     {
@@ -4563,41 +4803,45 @@
 
 STDMETHODIMP_(HXBOOL) CHXAudioSession::CanStartPowerSave (void)
 {
-    if (m_bHasStreams)
-    {
-        return FALSE;
-    }
-
-    if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+    HXBOOL retVal = FALSE;
+	
+    if (m_pPlayerList )
     {
-        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
-        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        return pPlayer->CanStartPowerSave();
+        if (m_pPlayerList->GetCount() == 1)
+        {
+            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+            CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+            retVal = pPlayer->CanStartPowerSave();
+        }
     }
 
-    return FALSE;
+    return retVal;
 }
 
-STDMETHODIMP_(ULONG32) CHXAudioSession::GetWakeUpInterval (void)
+STDMETHODIMP_(ULONG32) CHXAudioSession::GetWakeUpInterval ()
 {
+    ULONG32 ulWakeUpInterval = 0;
+	
     if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
     {
         CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
         CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        return pPlayer->GetWakeUpInterval();
+        ulWakeUpInterval = pPlayer->GetWakeUpInterval();
     }
-    return 0;
+    HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::GetWakeUpInterval(): ulWakeUpInterval = %lu ", ulWakeUpInterval);
+    return ulWakeUpInterval;
 }
 
-STDMETHODIMP_(ULONG32) CHXAudioSession::SetWakeUpInterval (ULONG32 /*IN*/ ulWakeUpInterval)
+STDMETHODIMP CHXAudioSession::SetWakeUpInterval(ULONG32 ulWakeUpInterval )
 {
+    HX_RESULT retVal = HXR_FAIL;
     if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
     {
         CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
         CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        return pPlayer->SetWakeUpInterval(ulWakeUpInterval);
+        retVal = pPlayer->SetWakeUpInterval(ulWakeUpInterval);
     }
-    return 0;
+    return retVal;
 }
 
 #endif /*HELIX_FEATURE_POWER_SAVE*/

 ---------------------------------------------------------------------------------------------------------------------
 
 Index: hxcleng.h
 ===================================================================
 RCS file: /cvsroot/client/core/pub/hxcleng.h,v
 retrieving revision 1.50.2.1
 diff -u -r1.50.2.1 hxcleng.h
 --- hxcleng.h	18 Sep 2009 04:46:03 -0000	1.50.2.1
 +++ hxcleng.h	31 Aug 2010 18:18:48 -0000
 @@ -76,6 +76,9 @@
  #define _MEDIUM_BLOCK 1
  #endif
  
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +#include  "hxPowerSave.h"
 +#endif /*HELIX_FEATURE_POWER_SAVE*/
  class	HXCommonClassFactory;
  class	HXScheduler;
  class   HXOptimizedSchedulerBase;
 @@ -137,10 +140,6 @@
  #endif
  #endif //HELIX_FEATURE_NETSERVICES
  
 -#if defined(HELIX_FEATURE_POWER_SAVE)
 -_INTERFACE IHXPowerSave;
 -#endif // HELIX_FEATURE_POWER_SAVE
 -
  #if defined(HELIX_FEATURE_SYSTEMREQUIRED)
  class HXSystemRequired : public IHXSystemRequired
  {
 @@ -624,7 +623,7 @@
      STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
      STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
      STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
 -    STDMETHOD_(ULONG32,SetWakeUpInterval)      ( THIS_ ULONG32 /*IN*/ ulWakeUpInterval );
 +    STDMETHOD(SetWakeUpInterval)               ( THIS_ ULONG32 ulWakeUpInterval );
  #endif /*HELIX_FEATURE_POWER_SAVE*/
  
  
 @@ -668,8 +667,9 @@
      HXTimeval*                    m_pCurrentTime;
  #endif /*HELIX_FEATURE_SYSTEM_EXTERNAL_TIMER*/
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -    HXBOOL			m_bInPowerSave;
 -    ULONG32			m_ulWakeUpInterval;
 +    HXBOOL             m_bInPowerSave;
 +    HXBOOL             m_bPowerSaveModeAllowed;
 +    ULONG32            m_ulWakeUpInterval;
  #endif /*HELIX_FEATURE_POWER_SAVE*/
  
  };
 -------------------------------------------------------------------------------------------------------------
 
 Index: hxcleng.cpp
 ===================================================================
 RCS file: /cvsroot/client/core/hxcleng.cpp,v
 retrieving revision 1.136.8.1.2.1
 diff -u -r1.136.8.1.2.1 hxcleng.cpp
 --- hxcleng.cpp	28 Apr 2010 20:52:56 -0000	1.136.8.1.2.1
 +++ hxcleng.cpp	31 Aug 2010 18:27:17 -0000
 @@ -388,6 +388,7 @@
  
  ,m_pContext(NULL)
  #if defined(HELIX_FEATURE_POWER_SAVE)
 +,m_bPowerSaveModeAllowed(FALSE)
  ,m_bInPowerSave(FALSE)
  ,m_ulWakeUpInterval(DEFAULT_WAKEUP_INTERVAL)
  #endif /*HELIX_FEATURE_POWER_SAVE*/
 @@ -858,7 +859,12 @@
          ReadPrefBOOL(m_pPreferences, "UseCoreThread", m_bUseCoreThread);  
      }
  #endif /*_WIN32*/
 +#ifdef HELIX_FEATURE_POWER_SAVE
  
 +	ReadPrefBOOL(m_pPreferences, "EnablePowerSaveMode", m_bPowerSaveModeAllowed);
 +	HXLOGL1( HXLOG_CORE, "Preferences values are: m_bPowerSaveModeAllowed %d ", m_bPowerSaveModeAllowed );
 +
 +#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
      InitializeThreadedObjects();
  
  #if defined(HELIX_FEATURE_AUDIO)
 @@ -1024,7 +1030,9 @@
          { GET_IIDHANDLE(IID_IHXAutoBWCalibrationAdviseSink), (IHXAutoBWCalibrationAdviseSink*)this },
  	{ GET_IIDHANDLE(IID_IHXContextUser), (IHXContextUser*)this },
  // #ifdef..
 +#ifdef HELIX_FEATURE_POWER_SAVE
  	{ GET_IIDHANDLE(IID_IHXPowerSave), (IHXPowerSave*)this }
 +#endif /*HELIX_FEATURE_POWER_SAVE*/
      };
      HX_RESULT retval = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
      if (retval == HXR_OK)
 @@ -2629,6 +2637,13 @@
   const char* pMoreInfoURL
   )
  {
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +    if (unSeverity != HXLOG_DEBUG   &&
 +        ulHXCode  != HXR_OK)
 +    {
 +        EndPowerSave();
 +    }
 +#endif
      if (m_PlayerList.GetCount())
      {
          HXPlayer* pHXPlayer = (HXPlayer*)m_PlayerList.GetTail();
 @@ -3036,25 +3051,32 @@
  #if defined(HELIX_FEATURE_POWER_SAVE)
  STDMETHODIMP_(HX_RESULT) HXClientEngine::StartPowerSave(void)
  {
 -    HX_RESULT theErr = HXR_OK;
 +    HX_RESULT theErr = HXR_FAIL;
 +    HXLOGL2( HXLOG_CORE, "HXClientEngine[%p]::StartPowerSave m_bPowerSaveModeAllowed:%d m_bInPowerSave:%d", this, m_bPowerSaveModeAllowed, m_bInPowerSave);
  
 -    if (!CanStartPowerSave())
 +    if (m_pCoreMutex)
      {
 -        return HXR_FAIL;
 +        m_pCoreMutex->Lock();
      }
 -
 -    if (m_pAudioSession)
 +    if (CanStartPowerSave())
      {
 -        m_ulWakeUpInterval = m_pAudioSession->SetWakeUpInterval(m_ulWakeUpInterval);
 -        theErr = m_pAudioSession->StartPowerSave();
 -
 -        /* Add the interval to HXPlayer */
 -        HX_ASSERT(GetPlayerCount() == 1);
 -
 -        HXPlayer* pPlayer = m_PlayerList.GetHead();
 -        if (pPlayer != NULL)
 +        if (m_pAudioSession)
          {
 -            pPlayer->AdjustWakeUpInterval(m_ulWakeUpInterval);
 +            m_pAudioSession->SetWakeUpInterval(m_ulWakeUpInterval);
 +            m_ulWakeUpInterval = m_pAudioSession->GetWakeUpInterval();
 +            theErr = m_pAudioSession->StartPowerSave();
 +
 +            /* Add the interval to HXPlayer */
 +            HX_ASSERT(GetPlayerCount() == 1);
 +            LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
 +            if (lPosition != NULL)
 +            {
 +                HXPlayer* pPlayer = (HXPlayer*) m_PlayerList.GetAt(lPosition);
 +                if (pPlayer != NULL)
 +                {
 +                    pPlayer->AdjustWakeUpInterval(m_ulWakeUpInterval);
 +                }
 +            }
          }
      }
  
 @@ -3067,27 +3089,39 @@
          EndPowerSave();
      }
  
 +    if (m_pCoreMutex)
 +    {
 +        m_pCoreMutex->Unlock();
 +    }
      return theErr;
  }
  
  STDMETHODIMP_(HX_RESULT) HXClientEngine::EndPowerSave(void)
  {
 -    HX_RESULT theErr = HXR_OK;
 -
 -    if (!IsInPowerSave())
 +   HXLOGL2( HXLOG_CORE, "HXClientEngine[%p]::EndPowerSave m_bPowerSaveModeAllowed:%d m_bInPowerSave:%d", this, m_bPowerSaveModeAllowed, m_bInPowerSave);
 +    HX_RESULT theErr = HXR_FAIL;
 +    if (m_pCoreMutex)
      {
 -        return HXR_FAIL;
 +        m_pCoreMutex->Lock();
      }
  
 -    if (m_pAudioSession)
 +    if (IsInPowerSave())
      {
 -        theErr = m_pAudioSession->EndPowerSave();
 +        if (m_pAudioSession)
 +        {
 +            theErr = m_pAudioSession->EndPowerSave();
 +        }
      }
  
      if (theErr == HXR_OK)
      {
          m_bInPowerSave = FALSE;
      }
 +	
 +    if (m_pCoreMutex)
 +    {
 +        m_pCoreMutex->Unlock();
 +    }
  
      return theErr;
  }
 @@ -3099,39 +3133,38 @@
  
  STDMETHODIMP_(HXBOOL) HXClientEngine::CanStartPowerSave(void)
  {
 -    if ((GetPlayerCount() > 1) || m_bInPowerSave)
 +    HXBOOL retVal = FALSE;
 +    if ((GetPlayerCount() == 1)&& !m_bInPowerSave && m_bPowerSaveModeAllowed)
      {
 -        return FALSE;
 -    }
 -
 -    LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
 -    if (lPosition != NULL)
 -    {
 -        HXPlayer* pPlayer = (HXPlayer*) m_PlayerList.GetAt(lPosition);
 -        if (pPlayer != NULL && !pPlayer->IsLocalSource())
 +        LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
 +        if (lPosition != NULL)
          {
 -            return FALSE;
 +            HXPlayer* pPlayer = (HXPlayer*) m_PlayerList.GetAt(lPosition);
 +            if (pPlayer && pPlayer->IsPowerSaveCapable()) 
 +            {
 +                if (m_pAudioSession)
 +                {
 +                    retVal = m_pAudioSession->CanStartPowerSave();
 +                }
 +            }     
          }
      }
  
 -    if (m_pAudioSession)
 -    {
 -        return m_pAudioSession->CanStartPowerSave();
 -    }
  
 -    return FALSE;
 +    return retVal;
  }
  
  STDMETHODIMP_(ULONG32) HXClientEngine::GetWakeUpInterval(void)
  {
 +    HXLOGL2( HXLOG_CORE, "HXClientEngine[%p]::GetWakeUpInterval  m_ulWakeUpInterval: %lu ",m_ulWakeUpInterval);
      return m_ulWakeUpInterval;
  }
  
 -STDMETHODIMP_(ULONG32) HXClientEngine::SetWakeUpInterval( ULONG32 /*IN*/ ulWakeUpInterval)
 +STDMETHODIMP HXClientEngine::SetWakeUpInterval( ULONG32  ulWakeUpInterval)
  {
      m_ulWakeUpInterval = ulWakeUpInterval;
  
 -    return m_ulWakeUpInterval;
 +    return HXR_OK;
  }
  
  #endif /*HELIX_FEATURE_POWER_SAVE*/
 

--------------------------------------------------------------------------------------------------------------------

Index: hxplay.h
===================================================================
RCS file: /cvsroot/client/core/pub/hxplay.h,v
retrieving revision 1.69.8.1
diff -u -r1.69.8.1 hxplay.h
--- hxplay.h	18 Sep 2009 04:46:03 -0000	1.69.8.1
+++ hxplay.h	31 Aug 2010 18:31:25 -0000
@@ -218,7 +218,9 @@
 /* Lowest allowable time sync granularity */
 #define MINIMUM_TIMESYNC_GRANULARITY	20
 
+
 #define DEFAULT_WAKEUP_INTERVAL		100
+
 #ifndef _WIN16
 //#if defined(HELIX_FEATURE_AUTHENTICATION)
 typedef WRAPPED_POINTER(IUnknown) Wrapped_IUnknown;
@@ -1649,13 +1651,15 @@
     {
         m_ulPlayerWakeUpInterval = ulWakeUpInterval;
     }
+    HXBOOL IsPowerSaveCapable();
+    HX_RESULT UpdatePowerSaveLimit();
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
     /* Examine all sources in the player.  If any source is a network 
        source (HXNetSource), it will fail.  If any source is a file 
        source (HXFileSource) and either a file or file format object 
        report NETWORKACCESS, it will fail. */
-    HXBOOL IsLocalSource();
+
 
     ////////////////////////////////////////////////////////////////////
     //
@@ -2252,6 +2256,7 @@
     IHXRecordService*	        m_pRecordService;
     HXBOOL                      m_bRecordServiceEnabled;
 
+    IHXScheduler3*              m_pScheduler3;
 #if defined(HELIX_FEATURE_POWER_SAVE)
     ULONG32                     m_ulPlayerWakeUpInterval;
 #endif

------------------------------------------------------------------------------------------------------------
Index: hxplay.cpp
===================================================================
RCS file: /cvsroot/client/core/hxplay.cpp,v
retrieving revision 1.200.8.1.2.1
diff -u -r1.200.8.1.2.1 hxplay.cpp
--- hxplay.cpp	9 Nov 2009 09:22:52 -0000	1.200.8.1.2.1
+++ hxplay.cpp	31 Aug 2010 18:36:40 -0000
@@ -430,6 +430,7 @@
     ,m_pSharedWallClocks(NULL)
     ,m_pRecordService(NULL)
     ,m_bRecordServiceEnabled(FALSE)
+    , m_pScheduler3(NULL)
 #if defined(HELIX_FEATURE_POWER_SAVE)
     ,m_ulPlayerWakeUpInterval(0)
 #endif //HELIX_FEATURE_POWER_SAVE
@@ -1673,6 +1674,11 @@
     CreateInstanceCCF(CLSID_IHXUpgradeCollection, (void**)&m_pUpgradeCollection, (IUnknown*)(IHXClientEngine*)m_pEngine);  
 #endif /* HELIX_FEATURE_AUTOUPGRADE */
 
+    HX_RELEASE(m_pScheduler3);
+    m_pScheduler->QueryInterface(IID_IHXScheduler3, (void**)&m_pScheduler3);
+
+    HXLOGL4( HXLOG_CORE, "HXPlayer::m_pScheduler3[%p]", m_pScheduler3);
+
     return theErr;
 }
 
@@ -6605,6 +6611,8 @@
     HX_RELEASE (m_pRegistry);
 #endif /* HELIX_FEATURE_REGISTRY */
 
+    HX_RELEASE(m_pScheduler3);
+
     HX_RELEASE (m_pEngine);
     HX_RELEASE (m_pClient);
     HX_RELEASE (m_pScheduler);
@@ -9590,7 +9598,10 @@
     {
         m_pAdviseSink->OnPosLength(m_ulCurrentPlayTime, m_ulPresentationDuration);
     }
+#ifdef HELIX_FEATURE_POWER_SAVE
 
+    UpdatePowerSaveLimit();
+#endif /*HELIX_FEATURE_POWER_SAVE*/
     return;
 }
 
@@ -11402,14 +11413,13 @@
 #endif  // _MACINTOSH
 
 #if defined(HELIX_FEATURE_POWER_SAVE) && defined(HELIX_FEATURE_AUDIO)
-    if (m_pAudioPlayer && m_pAudioPlayer->IsInPowerSave())
+    if (m_pAudioPlayer && m_pScheduler3 
+            && !m_pScheduler3->IsPaused()&& m_pAudioPlayer->IsInPowerSave())
     {
         // the actually interval from device may differ slightly from set from user (due to some alignment).
         // todo, do we need get this interval each time? 
         // is there possiblity that the interval modified from render/device unpredictably?
-        m_ulPlayerWakeUpInterval = m_pAudioPlayer->GetWakeUpInterval();
-        if (ulRet < m_ulPlayerWakeUpInterval)
-            ulRet = m_ulPlayerWakeUpInterval;//FIXME-Y
+        ulRet += m_ulPlayerWakeUpInterval;
     }
 #endif // (HELIX_FEATURE_POWER_SAVE) && (HELIX_FEATURE_AUDIO)
 
@@ -13958,22 +13968,33 @@
     }
 }
 
-HXBOOL HXPlayer::IsLocalSource()
+#ifdef HELIX_FEATURE_POWER_SAVE
+HX_RESULT HXPlayer::UpdatePowerSaveLimit()
 {
-    CHXMapPtrToPtr::Iterator iter = m_pSourceMap->Begin();
-    while(iter != m_pSourceMap->End())
+    HX_RESULT retVal = HXR_FAIL;
+    if(m_pAudioPlayer)
     {
-        SourceInfo* pSourceInfo = (SourceInfo*)(*iter);
-        HX_ASSERT (pSourceInfo != NULL);
+        HXLOGL1( HXLOG_CORE, "HXPlayer[%p]::UpdatePowerSaveLimit Limit:%lu", this, m_ulPresentationDuration);
+        retVal = m_pAudioPlayer->SetLimit (m_ulPresentationDuration);
+    }
+    return retVal;
+}
+
+HXBOOL HXPlayer::IsPowerSaveCapable()
+{
+    HXBOOL bPowerSaveCapable = FALSE;
+    if((m_pSourceMap != NULL) &&
+        (m_pSourceMap->GetCount() == 1) )
+    {
+        CHXMapPtrToPtr::Iterator    ndxSource;
+        ndxSource = m_pSourceMap->Begin();
+        SourceInfo* pSourceInfo = (SourceInfo*) (*ndxSource);
         HXSource* pSource = pSourceInfo->m_pSource;
-        if (pSource != NULL)
+        if(pSource && !(pSource->UsesNetworkAccess()))
         {
-            if (((HXSource*)pSource)->UsesNetworkAccess())
-            {
-                return FALSE;
-            }
+            bPowerSaveCapable = TRUE;
         }
-        ++iter;
-    }
-    return TRUE;
+    } 
+    return bPowerSaveCapable;
 }
+#endif /*HELIX_FEATURE_POWER_SAVE*/

--------------------------------------------------------------------------------------------------------

Index: chxmedpltfmsched.h
===================================================================
RCS file: /cvsroot/client/medpltfm/pub/chxmedpltfmsched.h,v
retrieving revision 1.7
diff -u -r1.7 chxmedpltfmsched.h
--- chxmedpltfmsched.h	6 Jul 2007 21:58:21 -0000	1.7
+++ chxmedpltfmsched.h	31 Aug 2010 18:47:47 -0000
@@ -57,8 +57,9 @@
 class CHXMediaPlatformKicker;
 
 class CHXMediaPlatformScheduler : public CUnknownIMP
-				, public IHXScheduler
-				, public IHXScheduler2
+                , public IHXScheduler
+                , public IHXScheduler2
+                , public IHXScheduler3
 {
 protected:
     UINT32			m_ulThreadID;
@@ -114,6 +115,9 @@
 						    ULONG32 ulTimeout);
     STDMETHOD_(ULONG32, GetThreadID)		    (THIS);
     STDMETHOD_(HXBOOL, AreImmediatesPending)	    (THIS);
+    STDMETHOD(PauseScheduler)   (THIS_);    
+    STDMETHOD(ResumeScheduler)  (THIS_);
+    STDMETHOD_(HXBOOL, IsPaused)  (THIS_);
 
     HX_RESULT	Init(IUnknown* pContext);
     HX_RESULT	AttachKicker(CHXMediaPlatformKicker* pKicker);

------------------------------------------------------------------------------------------------------------

Index: chxmedpltfmsched.cpp
===================================================================
RCS file: /cvsroot/client/medpltfm/chxmedpltfmsched.cpp,v
retrieving revision 1.8
diff -u -r1.8 chxmedpltfmsched.cpp
--- chxmedpltfmsched.cpp	6 Jul 2007 21:58:19 -0000	1.8
+++ chxmedpltfmsched.cpp	12 Aug 2010 22:15:54 -0000
@@ -60,6 +60,7 @@
 BEGIN_INTERFACE_LIST_NOCREATE(CHXMediaPlatformScheduler)
     INTERFACE_LIST_ENTRY_SIMPLE(IHXScheduler)
     INTERFACE_LIST_ENTRY_SIMPLE(IHXScheduler2)
+    INTERFACE_LIST_ENTRY_SIMPLE(IHXScheduler3)
     INTERFACE_LIST_ENTRY_DELEGATE(IID_IHXMutex, _InternalQIMutex)
 END_INTERFACE_LIST
 
@@ -213,6 +214,24 @@
     return m_pScheduler ? m_pScheduler->AreImmediatesPending() : FALSE; 
 }
 
+STDMETHODIMP
+CHXMediaPlatformScheduler::PauseScheduler()
+{
+    return m_pScheduler ? m_pScheduler->PauseScheduler() : HXR_FAILED;
+}
+
+STDMETHODIMP
+CHXMediaPlatformScheduler::ResumeScheduler()
+{
+    return m_pScheduler ? m_pScheduler->ResumeScheduler() : HXR_FAILED;
+}
+
+STDMETHODIMP_(HXBOOL)
+CHXMediaPlatformScheduler::IsPaused(void)
+{
+    return m_pScheduler ? m_pScheduler->IsPaused() : FALSE; 
+}
+
 HX_RESULT
 CHXMediaPlatformScheduler::_InternalQIMutex(REFIID riid, void** ppvObj)
 {

------------------------------------------------------------------------------------------------------------
Index: chxmedpltfm.cpp
===================================================================
RCS file: /cvsroot/client/medpltfm/chxmedpltfm.cpp,v
retrieving revision 1.78.4.3
diff -u -r1.78.4.3 chxmedpltfm.cpp
--- chxmedpltfm.cpp	7 Jul 2010 23:21:52 -0000	1.78.4.3
+++ chxmedpltfm.cpp	9 Aug 2010 16:27:22 -0000
@@ -1141,8 +1141,9 @@
         {
             rc = m_pMutex ? m_pMutex->QueryInterface(riid, ppvObj) : HXR_NOTIMPL;
         }
-        else if ((IsEqualIID(riid, IID_IHXScheduler) ||
-                  IsEqualIID(riid, IID_IHXScheduler2)))
+        else if (IsEqualIID(riid, IID_IHXScheduler) ||
+                  IsEqualIID(riid, IID_IHXScheduler2)||
+                  IsEqualIID(riid, IID_IHXScheduler3))
         {
             rc = m_pScheduler ? m_pScheduler->QueryInterface(riid, ppvObj) : HXR_NOTIMPL;
         }


---------------------------------------------------------------------------------------------------------------

Index: R1_Mobile_4_0_Factory.cfg
===================================================================
RCS file: /cvsroot/clientapps/symbiancommon/config/R1_Mobile_4_0_Factory.cfg,v
retrieving revision 1.57.4.5
diff -u -r1.57.4.5 R1_Mobile_4_0_Factory.cfg
--- R1_Mobile_4_0_Factory.cfg	17 Jun 2010 12:37:53 -0000	1.57.4.5
+++ R1_Mobile_4_0_Factory.cfg	26 Aug 2010 15:59:46 -0000
@@ -62,7 +62,7 @@
 LinkChar-MTD=2000
 BaseAdaptationTargetTime=5000
 UseCMMFHWDeviceAudioCodec=0
-UseWMACMMFHWDeviceAudioCodec=0
+UseWMACMMFHWDeviceAudioCodec=1
 MetaDataKeys=Title,Copyright,Author,Abstract,Genre,Performer,Album,Tracknumber,WM/AlbumTitle,WM/Year,WM/Text,WM/TrackNumber,WM/Genre,WM/Composer,WM/OriginalArtist,WM/Picture,WM/AudioFileURL,WM/Provider
 #Partial PlayBack values
 DisablePartialPlayback=0
@@ -155,3 +155,6 @@
 UDPFirewallKnock=1
 # Maximum preroll supported for local playback
 MaxVideoPreroll=4000
+
+# For Power Save feature with AudioController
+EnablePowerSaveMode=1

------------------------------------------------------------------------------------------------------------------

Index: hxmmfstatectrl.h
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/hxmmfstatectrl.h,v
retrieving revision 1.19.12.8
diff -u -r1.19.12.8 hxmmfstatectrl.h
--- hxmmfstatectrl.h	12 May 2010 19:27:56 -0000	1.19.12.8
+++ hxmmfstatectrl.h	24 Aug 2010 20:12:53 -0000
@@ -74,6 +74,9 @@
 #define HXR_SEND_BUFFER_START                     0x1
 #define HXR_SEND_BUFFER_COMPLETE                  0x2
 #define HXR_SEND_BUFFER_UNKNOWN                   0x4
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxPowerSave.h"
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
 
 #define POST_SEEK_TIMER_VALUE  5000*1000  //5 seconds
 
@@ -182,6 +185,8 @@
     virtual HX_RESULT StepFrames(TInt aStep);
 #endif
 
+    void StartPowerSave();
+    void EndPowerSave();
   protected:
     HXMMFPlayCtrl*        m_pPlayerControl;
     HXMMFState*           m_pCurrentState;
@@ -261,6 +266,11 @@
     UINT8     m_bufferStatus;
     HXBOOL    m_bVideoController;
     TThreadId m_clientTid;
+#ifdef HELIX_FEATURE_POWER_SAVE
+private:
+	IHXPowerSave* m_pPowerSave;
+	IHXScheduler3* m_pScheduler3;
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 };
 
 #endif _HX_MMF_STATE_CTRL_H_

------------------------------------------------------------------------------------------------------------

Index: hxmmfstatectrl.cpp
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/hxmmfstatectrl.cpp,v
retrieving revision 1.32.12.13
diff -u -r1.32.12.13 hxmmfstatectrl.cpp
--- hxmmfstatectrl.cpp	12 Jul 2010 16:43:48 -0000	1.32.12.13
+++ hxmmfstatectrl.cpp	31 Aug 2010 18:56:21 -0000
@@ -307,7 +307,16 @@
 ULONG32
 HXMMFStateCtrl::GetPosition()
 {
-    return(m_posLength);
+#ifdef HELIX_FEATURE_POWER_SAVE
+	if(m_pScheduler3
+	&& m_pScheduler3->IsPaused()
+	&& m_pPlayerControl
+	&& m_pPlayerControl->m_pHXPlayer)
+	{
+		m_posLength = m_pPlayerControl->m_pHXPlayer->GetCurrentPlayTime();
+	}
+#endif /*HELIX_FEATURE_POWER_SAVE*/
+	return m_posLength;
 }
 
 ULONG32
@@ -417,6 +426,10 @@
         HX_RELEASE(m_pSiteSupplier);
         HX_RELEASE(m_pClientEngine);
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+        HX_RELEASE(m_pPowerSave);
+        HX_RELEASE(m_pScheduler3);
+#endif /*HELIX_FEATURE_POWER_SAVE*/
         if(m_pPlayerControl != NULL)
         {
             if (m_pPlayerControl->m_pHXPlayer)
@@ -452,6 +465,10 @@
     , m_clientTid(0)
     , m_bPlayPending(FALSE)
     , m_bSurfaceCreated(FALSE)
+#ifdef HELIX_FEATURE_POWER_SAVE
+    ,m_pPowerSave(NULL)
+    ,m_pScheduler3(NULL)
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 {
     m_pSiteSupplier = NULL;
     m_pPrefs = NULL;
@@ -527,6 +544,13 @@
     {
         User::Leave(KErrNoMemory);
     }
+#ifdef HELIX_FEATURE_POWER_SAVE
+	//no need to  check the memory allocation here. It is done above.
+    m_pClientEngine->QueryInterface(IID_IHXPowerSave, (void**)&m_pPowerSave);
+
+    HX_RELEASE(m_pScheduler3);
+    QueryInterface(IID_IHXScheduler3, (void**)&m_pScheduler3);
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 
     InitAdviseSinks();
     SetupAPSelectorL();
@@ -1049,6 +1073,33 @@
 	return m_clientTid;
 }
 
+void HXMMFStateCtrl::StartPowerSave()
+{
+    HX_RESULT retVal = HXR_FAIL;
+
+
+#ifdef HELIX_FEATURE_POWER_SAVE
+    HXLOGL2( HXLOG_SMMF, "HXMMFStateCtrl::StartPowerSave  m_pPowerSave:%p", m_pPowerSave);
+    if(m_pPowerSave)
+    {
+        retVal = m_pPowerSave->StartPowerSave();
+    }
+#endif
+
+}
+
+
+void HXMMFStateCtrl::EndPowerSave()
+{
+#ifdef HELIX_FEATURE_POWER_SAVE
+    HXLOGL2( HXLOG_SMMF, "HXMMFStateCtrl::EndPowerSave  m_pPowerSave:%p", m_pPowerSave); 
+    if(m_pPowerSave)
+    {
+        m_pPowerSave->EndPowerSave();
+    }
+#endif
+
+}
 //Ensure timer is active.
 void HXMMFStateCtrl::SetOnPostSeekTimer()
 {  


---------------------------------------------------------------------------------------------------------

Index: hxmmfaudioctrl.h
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/audiocontroller/hxmmfaudioctrl.h,v
retrieving revision 1.9.32.5
diff -u -r1.9.32.5 hxmmfaudioctrl.h
--- hxmmfaudioctrl.h	4 May 2010 00:23:39 -0000	1.9.32.5
+++ hxmmfaudioctrl.h	31 Aug 2010 18:58:24 -0000
@@ -100,6 +100,7 @@
         virtual void PauseL();
         virtual void StopL();
         virtual void PrimeL();
+        virtual void SetPositionL(const TTimeIntervalMicroSeconds& aPosition);
 
         //
         //   MMMFAudioPlayControllerCustomCommandImplementor Methods


----------------------------------------------------------------------------------------------------------

Index: hxmmfaudioctrl.cpp
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/audiocontroller/hxmmfaudioctrl.cpp,v
retrieving revision 1.32.4.10
diff -u -r1.32.4.10 hxmmfaudioctrl.cpp
--- hxmmfaudioctrl.cpp	1 Jun 2010 04:04:20 -0000	1.32.4.10
+++ hxmmfaudioctrl.cpp	31 Aug 2010 19:00:42 -0000
@@ -258,6 +258,7 @@
         
         ResumeScheduler();
 
+        m_pStateCtrl->StartPowerSave();
 		
         if(m_uStartWindowPosition == TTimeIntervalMicroSeconds(0) &&
             m_uEndWindowPosition == DurationL())
@@ -976,7 +977,12 @@
 		}
         User::Leave(lError);
     }
-
+    // Pause the scheduler
+    if(m_bLocalPlayback)
+    {
+        HXLOGL1( HXLOG_SMMF, "CHXAudioController::AddDataSourceL() Pausing Scheduler");
+        PauseScheduler();
+    }
 }
 
 
@@ -1106,5 +1112,18 @@
 {
     return KErrNotSupported;
 }
+void
+CHXAudioController::SetPositionL( const TTimeIntervalMicroSeconds& aPosition )
+{	
+    HXLOGL1(HXLOG_SMMF, "CHXAudioController::SetPositionL() ");
+	
+    if(m_pStateCtrl != NULL)
+    {
+        m_pStateCtrl->EndPowerSave();
+	
+        HXMMFBaseCtrl::SetPositionL ( aPosition );
+    }
+
+}
     
 // End of File

---------------------------------------------------------------------------------------------------------

Index: hxmmfctrlimpl.cpp
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/videocontroller/hxmmfctrlimpl.cpp,v
retrieving revision 1.91.4.12
diff -u -r1.91.4.12 hxmmfctrlimpl.cpp
--- hxmmfctrlimpl.cpp	12 Jul 2010 16:43:47 -0000	1.91.4.12
+++ hxmmfctrlimpl.cpp	31 Aug 2010 19:04:24 -0000
@@ -1331,7 +1331,7 @@
     HXLOGL1(HXLOG_SMMF, "HXMMFCtrlImpl::OnPresentationClosed(m_closePlayer[%d])",m_closePlayer);
 
     TInt isLive = 0;
-
+    HXBOOL bPauseSched = FALSE;
 
     // seek the datasource to initial position.
     if (m_pDataSource)
@@ -1353,24 +1353,36 @@
         {
             SendEvent( m_nextEvent, m_ulLastError );
 
-            if(m_bLocalPlayback && m_ulLastError == HXR_OK)
-            {
-                PauseScheduler();
-            }
+            bPauseSched = TRUE;
 
         }
         m_nextEvent = ErrorEvent;
 
     }
-    else if (m_pMetaData)
+    else
+    {
+        if (m_pMetaData)
     {
         m_pMetaData->FindMetaDataValueByName("LiveStream",isLive);
 
         if (m_nextEvent == ErrorEvent && isLive)
         {
             SendEvent( ErrorEvent, HXR_CLOSED );
+            } 
+            else if(!isLive) 
+            {
+                bPauseSched = TRUE;
+            }
+        }
+        else
+        {
+            bPauseSched = TRUE;
         }
     }
+    if(m_bLocalPlayback && m_ulLastError == HXR_OK && bPauseSched)
+    {
+        PauseScheduler();
+    }
 }
 
---------------------------------------------------------------------------------------------------------------


Index: hxcore.h
===================================================================
RCS file: /cvsroot/common/include/hxcore.h,v
retrieving revision 1.24.2.1
diff -u -r1.24.2.1 hxcore.h
--- hxcore.h	18 Sep 2009 04:48:22 -0000	1.24.2.1
+++ hxcore.h	26 Aug 2010 15:31:58 -0000
@@ -2412,81 +2412,6 @@
  *
  */
 
-DEFINE_GUID(IID_IHXPowerSave, 0xf52067d2, 0xbf0b, 0x4081, 0xb3, 0x6f, 0xca, 0xee, 0x79, 0x24, 0x21, 0x9a);
-
-#undef  INTERFACE
-#define INTERFACE   IHXPowerSave
-
-DECLARE_INTERFACE_(IHXPowerSave, IUnknown)
-{
-     /*
-      * IUnknown methods
-      */
-     STDMETHOD(QueryInterface)		(THIS_
-					 REFIID riid,
-					 void** ppvObj) PURE;
-
-     STDMETHOD_(ULONG32,AddRef)		(THIS) PURE;
-
-     STDMETHOD_(ULONG32,Release)	(THIS) PURE;
-
-     /*
-      * IHXPowerSave methods
-      */
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::StartPowerSave
-      * Purpose:
-      *     same as EventOccurred with HX_POWERSAVE_ON
-      */
-     STDMETHOD(StartPowerSave)			(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::EndPowerSave
-      * Purpose:
-      *     same as EventOccurred with HX_POWERSAVE_OFF
-      */
-     STDMETHOD(EndPowerSave)			(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::IsInPowerSave
-      * Purpose:
-      *	    Check whether it is in power save mode. 
-      *     TRUE if operation on power save mode, FALSE otherwise
-      */
-     STDMETHOD_(HXBOOL,IsInPowerSave)		(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::CanStartPowerSave
-      * Purpose:
-      *     Check whether power-save-mode can be turned on.
-      *     TRUE if power save mode can be turned on at the time of the call.
-      */
-     STDMETHOD_(HXBOOL,CanStartPowerSave)	(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::GetWakeUpInterval
-      * Purpose:
-      *     Get time interval engine will nomally wake up in to operate
-      */
-     STDMETHOD_(ULONG32,GetWakeUpInterval)	(THIS) PURE;
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::SetWakeUpInterval
-      * Purpose:
-      *     Set time interval engine will nomally wake up in to operate  (use 
-      *     this only to override default)
-      */
-     STDMETHOD_(ULONG32,SetWakeUpInterval)	(THIS_ 
-						 ULONG32 /*IN*/ ulWakeUpInterval) PURE;
-
-};
-
 #include "hxcomptr.h"
 DEFINE_SMART_PTR(IHXStream)
 DEFINE_SMART_PTR(IHXStream2)
@@ -2517,9 +2442,6 @@
 DEFINE_SMART_PTR(IHXPlayerPresentation)
 DEFINE_SMART_PTR(IHXCoreMutex)
 DEFINE_SMART_PTR(IHXMacBlitMutex)
-#if defined(HELIX_FEATURE_POWER_SAVE)
-  DEFINE_SMART_PTR(IHXPowerSave)
-#endif /* defined(HELIX_FEATURE_POWER_SAVE) */
 
 #if defined _UNIX && !defined (_VXWORKS)
 DEFINE_SMART_PTR(IHXClientEngineSelector)

-------------------------------------------------------------------------------------------------------------------

Index: hxiids.h
===================================================================
RCS file: /cvsroot/common/include/hxiids.h,v
retrieving revision 1.168.4.4
diff -u -r1.168.4.4 hxiids.h
--- hxiids.h	7 Jul 2010 23:19:56 -0000	1.168.4.4
+++ hxiids.h	9 Aug 2010 16:29:30 -0000
@@ -425,6 +425,8 @@
 DEFINE_GUID_ENUM(IID_IHXPersistentComponent,    0x00000416, 0x901, 0x11d1, 0x8b, 0x6, 0x0, 0xa0, 0x24, 0x40, 0x6d, 0x59)
 DEFINE_GUID_ENUM(IID_IHXExternalSystemClock,            0x6de011a7, 0xef05, 0x417b, 0x93, 0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd5)
 DEFINE_GUID_ENUM(IID_IHXPowerSave,                      0xf52067d2, 0xbf0b, 0x4081, 0xb3, 0x6f, 0xca, 0xee, 0x79, 0x24, 0x21, 0x9a)
+DEFINE_GUID_ENUM(IID_IHXTimeLineLimit, 
+				0xb91a83e0, 0xef48, 0x11de, 0xaa, 0xca, 0x0, 0x2, 0xa5, 0xd5, 0xc5, 0x1b)
 // $Private:
 DEFINE_GUID_ENUM(IID_IHXSourceBufferingStats,       0x00000418, 0x901, 0x11d1, 0x8b, 0x6, 0x0, 0xa0, 0x24, 0x40, 0x6d, 0x59)
 DEFINE_GUID_ENUM(IID_IHXSourceBufferingStats2,       0x00000418, 0x901, 0x11d1, 0x8b, 0x6, 0x0, 0xa0, 0x24, 0x40, 0x6d, 0x5a)

--------------------------------------------------------------------------------------------------------------------

Index: hxengin.h
===================================================================
RCS file: /cvsroot/common/include/hxengin.h,v
retrieving revision 1.40
diff -u -r1.40 hxengin.h
--- hxengin.h	5 May 2009 16:26:33 -0000	1.40
+++ hxengin.h	9 Aug 2010 16:29:09 -0000
@@ -311,6 +311,8 @@
     STDMETHOD_(HXBOOL, AreImmediatesPending)(THIS) PURE;
 };
 
+#undef  INTERFACE
+#define INTERFACE   IHXScheduler3
 DECLARE_INTERFACE_(IHXScheduler3, IUnknown)
 {
     /*

--------------------------------------------------------------------------------------------------------------------
Index: helix-client-symbian-4-common.pfi
===================================================================
RCS file: /cvsroot/ribosome/build/umakepf/helix-client-symbian-4-common.pfi,v
retrieving revision 1.5
diff -u -r1.5 helix-client-symbian-4-common.pfi
--- helix-client-symbian-4-common.pfi	12 May 2010 19:25:47 -0000	1.5
+++ helix-client-symbian-4-common.pfi	7 Sep 2010 19:20:22 -0000
@@ -67,3 +67,6 @@
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_S60_AVKON')
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_VIDEOCTRL_PKG')
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_PHONON_PKG')
+
+project.AddDefines('HELIX_FEATURE_POWER_SAVE')
+

--------------------------------------------------------------------------------------------------------------------

Index: helix-client-symbian-4-integration-common.pfi
===================================================================
RCS file: /cvsroot/ribosome/build/umakepf/helix-client-symbian-4-integration-common.pfi,v
retrieving revision 1.6
diff -u -r1.6 helix-client-symbian-4-integration-common.pfi
--- helix-client-symbian-4-integration-common.pfi	12 May 2010 19:48:50 -0000	1.6
+++ helix-client-symbian-4-integration-common.pfi	7 Sep 2010 19:20:38 -0000
@@ -75,3 +75,5 @@
 project.RemoveDefines('HELIX_FEATURE_MMF_CUSTOM_COMMAND')
 project.RemoveDefines('HELIX_FEATURE_MMF_STREAM_CONTROL')
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_VIDEOCTRL_PKG')
+
+project.AddDefines('HELIX_FEATURE_POWER_SAVE')


 
 

-------------- next part --------------
#ifndef _HXPOWERSAVE_H_
#define _HXPOWERSAVE_H_




typedef _INTERFACE IHXPowerSave IHXPowerSave;

/****************************************************************************
*
*  Interface:
*
*	IHXPowerSave
*
*  Purpose:
*
*	Interface for IHXPowerSave objects.
*
*  IID_IHXPowerSave:
*
*   {F52067D2-BF0B-4081-B36F-CAEE7924219A}
*
*/

#undef INTERFACE
#define INTERFACE IHXPowerSave
DEFINE_GUID(IID_IHXPowerSave, 0xf52067d2, 0xbf0b, 0x4081, 0xb3, 0x6f, 0xca, 0xee, 0x79, 0x24, 0x21, 0x9a);

DECLARE_INTERFACE_(IHXPowerSave, IUnknown)
{

    /* IUnknown methods. */
    STDMETHOD(QueryInterface)   (THIS_ REFIID riid, void** ppvObj) PURE;
    STDMETHOD_(ULONG32,AddRef)  (THIS) PURE;
    STDMETHOD_(ULONG32,Release) (THIS) PURE;

	STDMETHOD(StartPowerSave) (THIS) PURE;
	STDMETHOD(EndPowerSave ) (THIS) PURE;
	STDMETHOD_(HXBOOL,IsInPowerSave) (THIS) PURE;
	STDMETHOD_(HXBOOL,CanStartPowerSave) (THIS) PURE;
	STDMETHOD_(ULONG32,GetWakeUpInterval ) (THIS) PURE;
	STDMETHOD(SetWakeUpInterval  ) (THIS_ ULONG32 ulWakeUpInterval ) PURE;
};


#endif /*_HXPOWERSAVE_H_*/
-------------- next part --------------
#ifndef _HXTIMELINELIMIT_H_
#define _HXTIMELINELIMIT_H_



typedef _INTERFACE IHXTimeLineLimit IHXTimeLineLimit;

/****************************************************************************
*
*  Interface:
*
*	IHXTimeLineLimit
*
*  Purpose:
*
*	Interface for IHXTimeLineLimit objects.
*
*  IID_IHXTimeLineLimit:
*
*	{b91a83e0-ef48-11de-aaca-0002a5d5c51b)
*
*/

#undef INTERFACE
#define INTERFACE IHXTimeLineLimit

DEFINE_GUID(IID_IHXTimeLineLimit, 0xb91a83e0, 0xef48, 0x11de, 0xaa, 0xca, 0x0, 0x2, 0xa5, 0xd5, 0xc5, 0x1b);

DECLARE_INTERFACE_(IHXTimeLineLimit, IUnknown)
{
	/* IUnknown methods. */
    STDMETHOD(QueryInterface)   (THIS_ REFIID riid, void** ppvObj) PURE;
    STDMETHOD_(ULONG32,AddRef)  (THIS) PURE;
    STDMETHOD_(ULONG32,Release) (THIS) PURE;
	
	STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs )PURE;
	STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs )PURE;
	STDMETHOD(ResetLimit) (THIS) PURE;
};

#endif /*_HXTIMELINELIMIT_H_*/
-------------- next part --------------
_______________________________________________
Clientapps-dev mailing list
Clientapps-dev@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/clientapps-dev
From xiaolin.lliu at nokia.com  Mon Sep 13 08:06:26 2010
From: xiaolin.lliu at nokia.com (xiaolin.lliu@nokia.com)
Date: Mon Sep 13 14:31:05 2010
Subject: [Helix-client-dev] RESEND: [datatype-dev] [Client-dev]
 [Clientapps-dev]
 [Nokia-private-dev]CR: Symbian	Add Power Save Support to Brizo420 and head
Message-ID: 

Skipped content of type multipart/alternative-------------- next part --------------

Index: mdfauddevice.h
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfauddevice.h,v
retrieving revision 1.10.10.1
diff -u -r1.10.10.1 mdfauddevice.h
--- mdfauddevice.h	9 Feb 2010 17:55:23 -0000	1.10.10.1
+++ mdfauddevice.h	31 Aug 2010 19:44:43 -0000
@@ -70,6 +70,10 @@
 #include "mdfaudfmt.h"
 #include "mdfauddata.h"
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxTimelineLimit.h"
+#include  "hxPowerSave.h"
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 // mdf device uses invalid value for initialization
 #define MDFDEVICE_INVALID_VOLUME -1 
 
@@ -80,6 +84,11 @@
                             public CActive,
                             public CHXMDFAudioDeviceObserver,
                             public IHXPropWatchResponse
+#ifdef HELIX_FEATURE_POWER_SAVE
+                           ,public IHXPowerSave
+                           ,public IHXTimeLineLimit
+                           ,public CHXPowerSaveAudDeviceObserver
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 {
 public:
     // factory method
@@ -148,7 +157,28 @@
     void SetStreamFinished(HXBOOL bEndOfStream);
 
     void StreamFinished();
-
+#ifdef HELIX_FEATURE_POWER_SAVE
+	/*Implement IHXTimeLineLimit*/
+    STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs );
+    STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs );
+    STDMETHOD(ResetLimit) (THIS);
+
+    /*Implement IHXPowerSave*/
+    STDMETHOD(StartPowerSave) (THIS);
+    STDMETHOD(EndPowerSave ) (THIS);
+    STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
+    STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
+    STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
+    STDMETHODIMP SetWakeUpInterval(THIS_ ULONG32 ulWakeUpInterval );
+    //
+    // CHXPowerSaveAudDeviceObserver methods
+    //
+    virtual void HighWaterMark();
+    virtual void LowWaterMark();
+protected:
+    HXBOOL IsDueStreamLimit();
+    void LoadPowerSaveCfg();
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 private:
     CHXMDFAudioDevice(HXMDFAudioFormat* pAudioFormat);      //constructor
     HX_RESULT Construct();          //two-phase constructor
@@ -179,6 +209,8 @@
 
     //Timing
     UINT32              m_ulAudioTimeOffset;    //rendering time
+    UINT32              m_ulCurrPlayTime;
+    HXBOOL              m_bDisableOnTimeSyncTimer;
         
     // buffered frames
     CHXSimpleList       m_bufferList;           //frames received from decoder
@@ -206,6 +238,24 @@
 
     HXBOOL              m_bEndOfStream; 
     HXBOOL              m_bEndOfStreamSent; 
+#ifdef HELIX_FEATURE_POWER_SAVE
+private:
+    IHXScheduler3*	m_pScheduler3;
+    HXBOOL m_bIsInPowerSave;
+    UINT32 m_ulWakeUpInterval;
+    UINT32 m_ulLowWaterMark;
+    UINT32 m_ulLimitDeviceInMs;
+    //last packet time passed to mdfDevsound Q
+    UINT32 m_ulLastAudioWrite;
+
+    //  Stat for power save config
+    UINT32 m_ulSchedulerPausedTime;
+    UINT32 m_ulSchedulerResumedTime;
+    UINT32 m_ulTotalSchedSleepTime;
+    UINT32 m_ulTotalSchedRunTime;
+
+
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 };
 
 ------------------------------------------------------------------------------------------------------------------

Index: mdfauddevice.cpp
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfauddevice.cpp,v
retrieving revision 1.19.4.7
diff -u -r1.19.4.7 mdfauddevice.cpp
--- mdfauddevice.cpp	8 Jun 2010 08:40:06 -0000	1.19.4.7
+++ mdfauddevice.cpp	31 Aug 2010 20:05:03 -0000
@@ -50,9 +50,15 @@
 #include "hxassert.h"
 #include "mdfauddevice.h"
 #include "mdfdebug.h"
+#include "hxtick.h" //HX_GET_BETTERTICKCOUNT()
 #include "hxprefutil.h"
 #include "hal.h" // for HAL::Get of ENanoTickPeriod
 
+#define DEFAULT_POWER_SAVE_HWM_MS   6000 //values are set in ms
+#define DEFAULT_POWER_SAVE_LWM_MS   2000 //values are set in ms
+// Offset is added to the HWM when wakeupinterval is calculated
+#define POWER_SAVE_HWM_OFFSET_MS       500
+
 
 static UINT32 Scale(UINT32 v, UINT32 f0, UINT32 f1, UINT32 t0, UINT32 t1);
 
@@ -122,6 +128,8 @@
         m_nBytesPCMToPlay(0),
         m_playing(FALSE),
         m_ulAudioTimeOffset(0),
+        m_ulCurrPlayTime(0),
+        m_bDisableOnTimeSyncTimer(FALSE),
         m_pAudioFormat(pAudioFormat),
         m_pErrorMessage(NULL),
         m_bDevTimeNeeded(TRUE),
@@ -132,6 +140,18 @@
         m_pPropWatch(NULL),
         m_bEndOfStream(FALSE)
         ,m_bEndOfStreamSent(FALSE)
+#ifdef HELIX_FEATURE_POWER_SAVE
+        ,m_pScheduler3(NULL)
+        ,m_bIsInPowerSave(FALSE)
+        ,m_ulWakeUpInterval (DEFAULT_POWER_SAVE_HWM_MS)
+        ,m_ulLowWaterMark(DEFAULT_POWER_SAVE_LWM_MS)
+        ,m_ulLimitDeviceInMs (0)
+        ,m_ulLastAudioWrite(0)
+        ,m_ulSchedulerPausedTime(0)
+        ,m_ulSchedulerResumedTime(HX_GET_BETTERTICKCOUNT())
+        ,m_ulTotalSchedSleepTime(0)
+        ,m_ulTotalSchedRunTime(0)
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 {
     //- activate active object
     CActiveScheduler::Add(this);
@@ -152,6 +172,18 @@
 CHXMDFAudioDevice::~CHXMDFAudioDevice()
 {
     HXLOGL4(HXLOG_MDFA,"mdfdev:~mdfdev <");
+#ifdef HELIX_FEATURE_POWER_SAVE
+    m_ulSchedulerPausedTime = HX_GET_BETTERTICKCOUNT();
+    UINT32 ulCurrSchedRunTime = m_ulSchedulerPausedTime - m_ulSchedulerResumedTime;
+    m_ulTotalSchedRunTime += ulCurrSchedRunTime;
+    UINT32 ulTotalSchedTime = m_ulTotalSchedRunTime + m_ulTotalSchedSleepTime;
+    HXLOGL1(HXLOG_MDFA,"------ Statistics of Power Save ----------");
+    HXLOGL1(HXLOG_MDFA, "CHXMDFAudioDevice[%p]::~CHXMDFAudioDevice PSave TotalRunTime:%lu TotSleepTime:%lu", this, m_ulTotalSchedRunTime, m_ulTotalSchedSleepTime);
+    HXLOGL1(HXLOG_MDFA, "CHXMDFAudioDevice[%p]::~CHXMDFAudioDevice PSave TotalRunTime:%lu Percent TotSleepTime:%lu percent", this,
+        ((m_ulTotalSchedRunTime *100 /ulTotalSchedTime)) , ((m_ulTotalSchedSleepTime*100 /ulTotalSchedTime)) );
+    HXLOGL1(HXLOG_MDFA,"------------------------------------------");
+    HX_RELEASE(m_pScheduler3);
+#endif // End of #ifdef HELIX_FEATURE_POWER_SAVE
     Close(TRUE);
     m_iTimer.Close();
 
@@ -209,6 +241,10 @@
             { GET_IIDHANDLE(IID_IHXTimelineWatcher), (IHXTimelineWatcher*)this },
             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXAudioDevice*)this },
             { GET_IIDHANDLE(IID_IHXPropWatchResponse), (IHXPropWatchResponse*)this },
+#ifdef HELIX_FEATURE_POWER_SAVE
+            { GET_IIDHANDLE(IID_IHXTimeLineLimit), (IHXTimeLineLimit*)this },
+            { GET_IIDHANDLE(IID_IHXPowerSave), (IHXPowerSave*)this },
+#endif /*HELIX_FEATURE_POWER_SAVE*/
         };
 
     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
@@ -295,6 +331,9 @@
         HX_RELEASE(m_pErrorMessage);
         m_pContext->QueryInterface(IID_IHXErrorMessages, (void **)&m_pErrorMessage);
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+        LoadPowerSaveCfg();
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
     }
     else
     {
@@ -351,8 +390,8 @@
 
 			m_bDevTimeNeeded = TRUE;	//now we need Dev Time
 				
-            GetCurrentAudioTime(ulAudioTime);
-            m_pDeviceResponse->OnTimeSync(ulAudioTime);
+            m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+            m_pDeviceResponse->OnTimeSync(m_ulCurrPlayTime);
         }
 
         //Set timer for next OnTimeSync callback
@@ -564,8 +603,8 @@
     if(m_pDeviceResponse)
     {
         ULONG32 ulAudioTime = 0;
-        GetCurrentAudioTime(ulAudioTime);
-        m_pDeviceResponse->OnTimeSync(ulAudioTime);
+        m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+        m_pDeviceResponse->OnTimeSync(m_ulCurrPlayTime);
     }
 
     DoSetTimer();
@@ -601,6 +640,10 @@
             HXLOGL4(HXLOG_MDFA,"mdfdev:write .. encoded data added");
             m_bufferList.RemoveHead();
             m_readyList.AddTail(pAudioData);
+#if defined HELIX_FEATURE_POWER_SAVE
+            m_ulLastAudioWrite = pAudioData->m_ulAudioTime-m_ulAudioTimeOffset;
+            m_pDevSound->SetLastRecvdEncodedData(m_ulLastAudioWrite);
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 
 #if defined(HELIX_FEATURE_LOGLEVEL_4) || defined(HELIX_FEATURE_LOGLEVEL_ALL)
             if ( pAudioData )
@@ -615,11 +658,12 @@
     {
         m_nBytesPCMToPlay += dataSize;
         
-        while(m_nBytesPCMToPlay >= m_pAudioFormat->m_uBytesPerFrame && m_pAudioFormat->m_uBytesPerFrame)
+        while(m_nBytesPCMToPlay >= m_pAudioFormat->m_uBytesPerFrame && m_pAudioFormat->m_uBytesPerFrame
+                && m_bEndOfStreamSent) 
         {
             m_readyList.AddTail(&m_pAudioFormat->m_fillerFrame);
             m_nBytesPCMToPlay -= m_pAudioFormat->m_uBytesPerFrame;
-            HXLOGL4(HXLOG_MDFA,"mdfdev:write .. adding filler frame");
+            HXLOGL4(HXLOG_MDFA,"mdfdev:write .. adding filler frame m_bEndOfStreamSent:%d", m_bEndOfStreamSent);
         }
     }
 
@@ -708,6 +752,7 @@
     //reset SecureOutput settings
     m_bSecureOutputChanged = FALSE;
 
+    m_ulCurrPlayTime = 0; 
     // stop device.
     if (m_pDevSound)
     {
@@ -767,11 +812,11 @@
 
 	if (pAudioFormat) {
         if (m_pAudioFormat->m_uChannels == pAudioFormat->uChannels &&
-        		m_pAudioFormat->m_uBitsPerSample == pAudioFormat->uBitsPerSample &&
-        		m_pAudioFormat->m_ulSamplesPerSec == pAudioFormat->ulSamplesPerSec) {
+            m_pAudioFormat->m_uBitsPerSample == pAudioFormat->uBitsPerSample &&
+            m_pAudioFormat->m_ulSamplesPerSec == pAudioFormat->ulSamplesPerSec) {
         			res = HXR_OK;
         		}
-    }
+	}
     return res;
 }
 
@@ -784,32 +829,55 @@
 
     HX_RESULT hxr = HXR_OK;
 
-    UINT32 systemTime=(UINT32)(((UINT64)User::NTickCount() * 1000) / m_systemTickPeriodInMicroSecond); 
+  //  UINT32 systemTime=(UINT32)(((UINT64)User::NTickCount() * 1000) / m_systemTickPeriodInMicroSecond); 
 
-    if (m_bDevTimeNeeded) {
-        hxr = m_pDevSound->GetCurrentPlayTime(ulCurrentTime);  //Dev Time
-        m_devTime = ulCurrentTime;
-        if (m_ulLastTime>ulCurrentTime) {
+#ifdef HELIX_FEATURE_POWER_SAVE
+    //  If scheduler is not running, the playback time is not current.
+    //  Update the current playback time
+    if(m_bIsInPowerSave && m_pScheduler3 && m_pScheduler3->IsPaused())
+    {
+        hxr = m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+        ulCurrentTime = m_ulCurrPlayTime;
+    }
+    else	
+#endif 
+    {
+        UINT32 systemTime=(UINT32)(((UINT64)User::NTickCount() * 1000) / m_systemTickPeriodInMicroSecond); 
+        if (m_bDevTimeNeeded)             
+        {
+            hxr = m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);  //Dev Time
+            ulCurrentTime = m_ulCurrPlayTime;
+            m_devTime = ulCurrentTime;
+            if (m_ulLastTime>ulCurrentTime) 
+            {
             // Device time ahead of computed time:
             //   return last computed time
-            ulCurrentTime=m_ulLastTime;
-        }
-        m_systemTimeMark = systemTime;
-        m_bDevTimeNeeded = FALSE;				//no need to check Dev Time.
-    } else {
-        // Don't ask time to device: compute using elapsed system time
-        LONG32 elapse = systemTime - m_systemTimeMark;
-        // Case of 32 bit counter overflow
-        if (elapse < 0) elapse= -elapse;
-        ulCurrentTime = m_devTime + elapse;		//interpolation
-        if (m_ulLastTime>ulCurrentTime) {
+                ulCurrentTime=m_ulLastTime;
+            }
+            m_systemTimeMark = systemTime;
+            m_bDevTimeNeeded = FALSE;				//no need to check Dev Time.
+        } 
+        else 
+        {
+            // Don't ask time to device: compute using elapsed system time
+            LONG32 elapse = systemTime - m_systemTimeMark;
+            // Case of 32 bit counter overflow
+            if (elapse < 0) elapse= -elapse;
+            ulCurrentTime = m_devTime + elapse;		//interpolation xaliu
+
+            if (m_ulLastTime>ulCurrentTime) 
+			{
             // New computed time still behind last computed time:
             //   return last computed time until new computed time goes ahead
-            ulCurrentTime=m_ulLastTime;
-        } else {
-            m_ulLastTime=ulCurrentTime;
-        }
-     } 
+                ulCurrentTime=m_ulLastTime;
+            } 
+            else 
+            {
+                m_ulLastTime=ulCurrentTime;
+            }
+        } 
+    }
+
 #if defined(HELIX_FEATURE_DRM_SECURE_OUTPUT)
 	if(m_bSecureOutputChanged) 
 	{
@@ -893,6 +961,7 @@
     HXLOGL4(HXLOG_MDFA,"mdfdeV:setStartT <> %d", ulStartTime);
 
     m_ulAudioTimeOffset = ulStartTime;
+    m_pDevSound->SetAudioTimeOffset(m_ulAudioTimeOffset); 
 }
 
 void CHXMDFAudioDevice::SetStreamFinished(HXBOOL bEndOfStream)
@@ -935,7 +1004,7 @@
 {
     HXLOGL4(HXLOG_MDFA,"mdfdeV:dosettimer <");
 
-    if( !IsActive())
+    if( (!IsActive()) && (!m_bDisableOnTimeSyncTimer)) 
     {
         //HXLOGL4(HXLOG_MDFA, "mdfdeV:dosettimer .. set timer here. %d", iStatus.Int());
         m_iTimer.After(iStatus, m_TimeSyncPeriodInMs * 1000);
@@ -953,7 +1022,9 @@
     HXLOGL4(HXLOG_MDFA, "mdfdeV:OnDeviceError <");
 
     HX_ASSERT(m_pErrorMessage != NULL);
-
+#ifdef HELIX_FEATURE_POWER_SAVE
+    EndPowerSave();
+#endif /*HELIX_FEATURE_POWER_SAVE*/
     // Report error to Error Messages
     if(m_pErrorMessage)
     {
@@ -1014,6 +1085,227 @@
 }
 
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+void CHXMDFAudioDevice::LoadPowerSaveCfg()
+{
+    if(m_pContext != NULL)
+    {
+        IHXPreferences* pPreference = NULL;
+        if(SUCCEEDED(m_pContext->QueryInterface(IID_IHXPreferences, (void**) &pPreference)))
+        {
+            // High water mark is same as wake up interval
+            UINT32 hwm = 0;
+            UINT32 lwm = 0;
+            if (SUCCEEDED(ReadPrefUINT32(pPreference, "PowerSaveHWM", hwm)) 
+                    && SUCCEEDED(ReadPrefUINT32(pPreference, "PowerSaveLWM", lwm)))            
+            {
+                if (lwm < hwm)
+                {
+                    m_ulWakeUpInterval = hwm;
+                    m_ulLowWaterMark = lwm;
+                }
+            }
+            HX_RELEASE(pPreference);
+        }
+    }
+    HXLOGL2(HXLOG_MDFA, "mdfdeV:LoadPowerSaveCfg HWM:%lu LWM:%lu ", m_ulWakeUpInterval, m_ulLowWaterMark);
+}
+HXBOOL CHXMDFAudioDevice::IsDueStreamLimit()
+{
+    HXBOOL bReachingStreamLimit = FALSE;
+    if((m_bIsInPowerSave) && m_ulLimitDeviceInMs != 0)
+    {
+        ULONG32 ulAudioTime = 0;
+        GetCurrentAudioTime(ulAudioTime);
+        //get the time left
+        ulAudioTime = (ULONG32)m_ulLimitDeviceInMs - ulAudioTime;
+
+        //if we are reaching the end of file
+        if( ulAudioTime < (ULONG32)m_ulWakeUpInterval)
+        {
+            bReachingStreamLimit = TRUE;
+        }
+    }
+
+    HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::IsDueStreamLimit bReachingStreamLimit[%d] ", this, bReachingStreamLimit);
+
+    return bReachingStreamLimit;
+}
+STDMETHODIMP
+CHXMDFAudioDevice::SetLimit (UINT32 ulLimitInMs )
+{
+    m_ulLimitDeviceInMs = ulLimitInMs;
+
+    HX_RESULT retVal = HXR_OK;
+    HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::SetLimit retVal=%x ", this, retVal);
+    return retVal;
+}
+
+STDMETHODIMP
+CHXMDFAudioDevice::GetLimit (UINT32 &ulLimitInMs )
+{
+   ulLimitInMs = m_ulLimitDeviceInMs;
+
+   HX_RESULT retVal = HXR_OK;
+   HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::GetLimit retVal=%x ", this, retVal);
+   return retVal;
+}
+
+STDMETHODIMP
+CHXMDFAudioDevice::ResetLimit ()
+{
+    m_ulLimitDeviceInMs = 0;
+
+    return HXR_OK;
+}
+
+
+/*Implement IHXPowerSave*/
+STDMETHODIMP
+CHXMDFAudioDevice::StartPowerSave()
+{
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::StartPowerSave ", this);
+
+    HX_RESULT retVal = HXR_OK;
+    if(!m_bIsInPowerSave)
+    {
+        HX_RELEASE(m_pScheduler3);
+        retVal = m_pContext->QueryInterface(IID_IHXScheduler3, (void**) &m_pScheduler3);
+
+        if(m_pScheduler3 != NULL)
+        {
+            //set value to true for active
+            m_bIsInPowerSave = TRUE;
+            m_pDevSound->SetPowerSaveConfig((CHXPowerSaveAudDeviceObserver*)this, m_ulWakeUpInterval, m_ulLowWaterMark);
+        } // End of if(m_pScheduler3 != NULL)
+        else 
+        {
+            HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::StartPowerSave Can not query Scheduler3");
+            retVal = HXR_FAIL;
+        }
+    }
+
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::StartPowerSave retVal=%x ", this, retVal);
+
+    return retVal;
+}
+
+
+STDMETHODIMP
+CHXMDFAudioDevice::EndPowerSave()
+{
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::EndPowerSave ", this);
+
+    HX_RESULT retVal = HXR_OK;
+    if(m_bIsInPowerSave)
+    {
+        HXLOGL3( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::EndPowerSave calling ResumeScheduler ", this);
+        LowWaterMark();
+        m_pDevSound->SetPowerSaveConfig(NULL, m_ulWakeUpInterval, m_ulLowWaterMark); //as such LowWaterMArk won't be called
+        m_bIsInPowerSave = FALSE;
+
+    } // End of if(m_bIsInPowerSave)
+
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::EndPowerSave retVal=%x ", this, retVal);
+
+    return retVal;
+}
+STDMETHODIMP_(HXBOOL)
+CHXMDFAudioDevice::IsInPowerSave()
+{
+    HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::IsInPowerSave m_bIsInPowerSave=%d ", this, m_bIsInPowerSave);
+    return m_bIsInPowerSave;
+}
+
+STDMETHODIMP_(HXBOOL)
+CHXMDFAudioDevice::CanStartPowerSave()
+{
+    HXBOOL bCanStart = TRUE;
+    HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::CanStartPowerSave bCanStart:%d", this, bCanStart);
+    return bCanStart;
+}
+
+STDMETHODIMP_(ULONG32)
+CHXMDFAudioDevice::GetWakeUpInterval()
+{
+    ULONG32 ulWakeUpInterval = m_ulWakeUpInterval;
+    // Adding an offset, so that the source does not stop sending data based on old playback time.
+    ulWakeUpInterval += POWER_SAVE_HWM_OFFSET_MS;
+    HXLOGL2( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::GetWakeUpInterval m_ulWakeUpInterval=%lu ", this, m_ulWakeUpInterval);
+
+    return ulWakeUpInterval;
+}
+STDMETHODIMP 
+CHXMDFAudioDevice::SetWakeUpInterval(ULONG32 ulWakeUpInterval )
+{
+    HXLOGL1( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::SetWakeUpInterval --WARNING-- luWakeUpInterval=%lu", this, ulWakeUpInterval);
+	//
+    // Does not accept other values from core
+    //
+    return HXR_FAIL;	
+}
+void CHXMDFAudioDevice::HighWaterMark()
+{
+    if(m_bIsInPowerSave)
+    {
+        HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::HighWaterMark calling IsDueStreamLimit()", this);
+
+        //when reaching the end of file we don't want to go to sleep
+        if(!IsDueStreamLimit())
+        {
+            if( !m_pScheduler3->IsPaused() )
+            {
+                m_ulSchedulerPausedTime = HX_GET_BETTERTICKCOUNT();
+                UINT32 ulCurrSchedRunTime = m_ulSchedulerPausedTime - m_ulSchedulerResumedTime;
+                m_ulTotalSchedRunTime += ulCurrSchedRunTime;
+                HXLOGL2( HXLOG_MDFA, "CHXAudioDevice[%p]::HighWaterMark PSave PauseScheduler RunTime:%lu TotRun:%lu", this, ulCurrSchedRunTime, m_ulTotalSchedRunTime);
+                m_pScheduler3->PauseScheduler();
+            }
+
+            m_bDisableOnTimeSyncTimer = TRUE;
+			m_bDevTimeNeeded = TRUE;
+
+            // Cancel the timer used for ontimesync reporting
+            if (IsActive())
+            {
+                HXLOGL3( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::Calling cancel ", this);
+                Cancel();
+            }
+        } // End of if(!IsDueStreamLimit())
+    } // End of if(m_bIsInPowerSave)
+
+}
+
+
+void CHXMDFAudioDevice::LowWaterMark()
+{
+    HXLOGL4( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::LowWaterMark m_bIsInPowerSave:%d ", this, m_bIsInPowerSave);
+
+    if(m_bIsInPowerSave)
+    {
+        if( m_pScheduler3->IsPaused() )
+        {
+            m_ulSchedulerResumedTime = HX_GET_BETTERTICKCOUNT();
+            UINT32 ulCurrSchedSleepTime = m_ulSchedulerResumedTime - m_ulSchedulerPausedTime;
+            m_ulTotalSchedSleepTime += ulCurrSchedSleepTime;
+            HXLOGL2( HXLOG_MDFA, "CHXAudioDevice[%p]::LowWaterMark PSave ResumeScheduler PauseTime:%lu TotPause:%lu", this, ulCurrSchedSleepTime, m_ulTotalSchedSleepTime);
+
+            m_pScheduler3->ResumeScheduler();
+        }
+
+        //set timer for OntimeSync or unpause timer for ontimesync
+        m_bDisableOnTimeSyncTimer = FALSE;
+        m_bDevTimeNeeded = TRUE;
+        if( !IsActive())
+        {
+            m_pDevSound->GetCurrentPlayTime(m_ulCurrPlayTime);
+            HXLOGL3( HXLOG_MDFA, "CHXMDFAudioDevice[%p]::LowWaterMark calling SetActive ", this);
+            DoSetTimer();
+        }
+    } // End of if(m_bIsInPowerSave)
+}
+
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 //
 // convenience methods
 //

--------------------------------------------------------------------------------------------------------------------


Index: mdfdevsound.h
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfdevsound.h,v
retrieving revision 1.17.4.2
diff -u -r1.17.4.2 mdfdevsound.h
--- mdfdevsound.h	4 May 2010 08:16:41 -0000	1.17.4.2
+++ mdfdevsound.h	31 Aug 2010 19:20:51 -0000
@@ -62,6 +62,10 @@
 #include "mdfdevconfig.h"
 #include "CHXAudioOutputConfigUtil.h"
 
+//***************************************************************//
+//For the power save mode
+class CHXPowerSaveAudDeviceObserver;
+//***************************************************************//
 class CHXMDFAudioDevice;
 class CHXMDFAudioDeviceObserver;
 class CHXMMFDevSound;
@@ -142,6 +146,13 @@
     
         // helper
         void SetAudioDeviceObserver(CHXMDFAudioDeviceObserver* p) {m_pDevObserver=p;};
+    //for power save
+        void SetPowerSaveConfig(CHXPowerSaveAudDeviceObserver* pPowSaveAudDevObserver, const UINT32& ulHighWaterMark, const UINT32& ulLowWaterMark);
+        void CheckForLWM();
+        void CheckForHWM();
+        void GetTotalUnPlayedDataInMs( UINT32& ulUnPlayedData);
+        void SetLastRecvdEncodedData(const UINT32& ulLastAudioWrite);
+        void SetAudioTimeOffset(UINT32 ulAudioTimeOffset) {m_ulAudioTimeOffset = ulAudioTimeOffset;}
         
     private:
         // constructor
@@ -206,6 +217,16 @@
         // status observer. only one in this implementation
         CHXMDFAudioDeviceObserver*     m_pDevObserver;
         
+    private:
+	
+        UINT32 m_ulHighWaterMark;
+        UINT32 m_ulLowWaterMark;
+        UINT32 m_ulLastEncodedWriteTime;
+        UINT32 m_ulLastDevWriteTime;
+        UINT32 m_ulAudioTimeOffset;
+        HXBOOL m_bDetectedHWM;
+        CHXPowerSaveAudDeviceObserver*     m_pPowSaveAudDevObserver;
+        
     // methods for FourCC            
     private:
 #ifdef _DEBUG_TEST_AUDIO_DEVICE_TAKEN_
@@ -231,4 +252,10 @@
         virtual void OnDeviceError(HX_RESULT hxr) = 0;
 };
 
+class CHXPowerSaveAudDeviceObserver
+{
+    public:
+        virtual void HighWaterMark() = 0;
+        virtual void LowWaterMark() = 0;
+};
 #endif


--------------------------------------------------------------------------------------------------------------------


Index: mdfdevsound.cpp
===================================================================
RCS file: /cvsroot/datatype/mdf/audio/dsp/mdfdevsound.cpp,v
retrieving revision 1.28.4.5
diff -u -r1.28.4.5 mdfdevsound.cpp
--- mdfdevsound.cpp	6 May 2010 03:34:26 -0000	1.28.4.5
+++ mdfdevsound.cpp	31 Aug 2010 19:37:50 -0000
@@ -150,6 +150,13 @@
 #ifdef _DEBUG_TEST_AUDIO_DEVICE_TAKEN_
     		,m_lErrCnt(1)
 #endif 
+            , m_ulHighWaterMark(0)
+            , m_ulLowWaterMark(0)
+            , m_ulLastEncodedWriteTime(0)
+            , m_ulLastDevWriteTime(0)
+            , m_ulAudioTimeOffset(0)
+            , m_pPowSaveAudDevObserver(NULL)
+            ,m_bDetectedHWM(FALSE)
 {
     HX_ASSERT(pFrameList);
     HX_ASSERT(pFormat);
@@ -337,8 +344,11 @@
     m_ulSamplesPlayedOffset = GetValidSamplesPlayed(); //BySamplesPlayed
 
 	//samples played before taken and samples written reset to zero
-	m_ulSamplesPlayedBeforeTaken = 0;
-
+    m_ulSamplesPlayedBeforeTaken = 0;
+    m_ulLastDevWriteTime = 0;
+    m_ulLastEncodedWriteTime = 0;
+    m_ulAudioTimeOffset = 0;
+    m_bDetectedHWM = FALSE;
     
     HXLOGL2(HXLOG_MDFA, "---devsnd:reset .. before flush %lu", (UINT32)m_ulSamplesPlayedOffset);
 
@@ -351,8 +361,10 @@
     {
         HX_ASSERT(m_pAddedDevSoundCI);
 		m_devStatus = DevPaused;
-        lError = m_pAddedDevSoundCI->PauseAndFlush();
-
+        if(m_pAddedDevSoundCI != NULL)
+        {
+            lError = m_pAddedDevSoundCI->PauseAndFlush();
+        }
         if (lError!=KErrNone) return HXR_FAIL;
 
     #if defined(HELIX_FEATURE_LOGLEVEL_4)
@@ -412,7 +424,7 @@
 {
     PRINTCURRENTSTATE("---devsnd:PLAY <");
 
-    if (m_devStatus == DevPaused)
+    if ((m_devStatus == DevPaused) || (m_devStatus == DevInitialized) )
     {   //resume
         if (m_pDevSoundBuffer)  // we have the dev buffer
         {
@@ -898,7 +910,6 @@
     }
 
     // -- Start playback loop --
-    StartPlayback();
 
     HXLOGL4(HXLOG_MDFA, "---devsnd:InitComp > %d", aError);
 }
@@ -948,7 +959,7 @@
     else
     {
         HXMDFAudioData* pAudioData = (HXMDFAudioData*)m_pDataList->GetHead();
-        UINT32 ulDataTime = pAudioData->m_ulAudioTime;
+        m_ulLastDevWriteTime = pAudioData->m_ulAudioTime - m_ulAudioTimeOffset;
 
         HX_RESULT retErr = HXR_OK;
         if (pAudioData->m_bMissing || pAudioData->m_bConcealed)
@@ -1017,6 +1028,7 @@
             m_ulFramesPlayedLastRound = 1;
             m_pDevSoundBuffer = NULL;
             m_pDevSound->PlayData();
+            CheckForLWM(); 
        }
         else
         {
@@ -1144,6 +1156,115 @@
 }
 
 
+//
+//  CMDFDevSound::SetPowerSaveConfig
+// 
+void CMDFDevSound::SetPowerSaveConfig(CHXPowerSaveAudDeviceObserver* pPowSaveAudDevObserver
+											, const UINT32& ulHighWaterMark
+											, const UINT32& ulLowWaterMark)
+{
+    HXLOGL2(HXLOG_MDFA,"CMDFDevSound::SetPowerSaveConfig m_ulHighWaterMark =%d, m_ulLowWaterMark =%d", m_ulHighWaterMark, m_ulLowWaterMark);
+
+    m_ulHighWaterMark = ulHighWaterMark;
+    m_ulLowWaterMark = ulLowWaterMark;
+    m_pPowSaveAudDevObserver = pPowSaveAudDevObserver;
+}
+
+//
+//  CMDFDevSound::SetLastRecvdEncodedData
+//  Timestamp of last encoded frame in Q
+// 
+void CMDFDevSound::SetLastRecvdEncodedData(const UINT32& ulLastAudioWrite)
+{
+    m_ulLastEncodedWriteTime = ulLastAudioWrite;
+    CheckForHWM();
+    HXLOGL4(HXLOG_CORE,"mdfdev:Write .. Obs:%p last buf time:%lu", m_pPowSaveAudDevObserver, ulLastAudioWrite);
+}
+
+//
+//  CMDFDevSound::CheckForHWM
+//  Checks if Q has reached high water mark
+//  and report to the observer
+// 
+void CMDFDevSound::CheckForHWM()
+{
+    //  Check if we have enough data to report
+    //  high water mark
+
+    //  We are not checking for m_bDetectedHWM as this call
+    //  should not happen when it is TRUE
+    //
+    if(m_pPowSaveAudDevObserver != NULL)
+    {
+        UINT32 ulTimeLeft = 0;
+        UINT32 ulTimeInDev = 0;
+
+        // First caluclate the data in Q
+        ulTimeLeft = m_ulLastEncodedWriteTime - m_ulLastDevWriteTime;
+
+        //  We use the last updated samples played
+        //  Inaccuracy could be upto 30msec as it is updated from during
+        //  the ontimesync reporting
+        ulTimeInDev = (m_ulLastValidSamplesPlayed - m_ulSamplesPlayedOffset)  * 1000 / m_pAudioFormat->m_ulSamplesPerSec;
+        ulTimeInDev = m_ulLastDevWriteTime - ulTimeInDev;
+
+        ulTimeLeft += ulTimeInDev;
+
+        HXLOGL4(HXLOG_MDFA,"mdfdev:CheckForHWM .. DataInQ:%lu m_ulLastDevWriteTime:%lu",ulTimeLeft, m_ulLastDevWriteTime);
+        
+        if(ulTimeLeft > m_ulHighWaterMark)
+        {
+            m_pPowSaveAudDevObserver->HighWaterMark();
+            HXLOGL4(HXLOG_MDFA,"devsnd:CheckForHWM .. m_bDetectedHWM=%d", m_bDetectedHWM);
+            m_bDetectedHWM = TRUE;
+        }
+    } // End of if(m_pPowSaveAudDevObserver != NULL)
+}
+
+//
+//  CMDFDevSound::CheckForLWM
+//  Checks if Q is below low water mark
+//  and reports to the observer
+// 
+void CMDFDevSound::CheckForLWM()
+{
+    HXLOGL4(HXLOG_MDFA,"devsnd:CheckForLWM .. m_bDetectedHWM=%d", m_bDetectedHWM);
+    if( (m_pPowSaveAudDevObserver != NULL) && (m_bDetectedHWM) )
+    {
+        UINT32 ulDataInQ = m_ulLastEncodedWriteTime - m_ulLastDevWriteTime;
+
+        HXLOGL4(HXLOG_MDFA,"devsnd:CheckForLWM .. ulDataInQ=%lu", ulDataInQ);
+        // We first check, if data in Q is nearing LWM. 
+        // This will reduce the number of samplesplayed calculation
+        if(ulDataInQ < m_ulLowWaterMark)
+        {
+            UINT32 ulTotalUnplayedDataInMs = 0;
+            // Calculate accurate unplayed samples time
+            GetTotalUnPlayedDataInMs(ulTotalUnplayedDataInMs);
+            HXLOGL4(HXLOG_MDFA,"devsnd:CheckForLWM .. Pending=%lu Obs:%p", ulTotalUnplayedDataInMs, m_pPowSaveAudDevObserver);
+            if(ulTotalUnplayedDataInMs <= m_ulLowWaterMark)
+            {
+                m_pPowSaveAudDevObserver->LowWaterMark();
+                m_bDetectedHWM = FALSE;
+            }
+        } // End of if(ulDataInQ < m_ulLowWaterMark)
+
+    } // End of if( (m_pPowSaveAudDevObserver != NULL) && (!m_bDetectedHWM) )
+}
+
+//
+//  CMDFDevSound::GetTotalUnPlayedDataInMs
+//  Returns the amount of unplayed 
+//  data(including data sent to devsound)
+// 
+void CMDFDevSound::GetTotalUnPlayedDataInMs( UINT32& ulUnPlayedData)
+{
+    UINT32 ulPlayTime = 0;
+    GetCurrentPlayTime(ulPlayTime);
+    ulUnPlayedData = m_ulLastEncodedWriteTime - ulPlayTime;
+}
+
+
 //--------------------
 //  Static Methods
 //--------------------


-------------------------------------------------------------------------------------------------------------------


Index: hxaudply.h
===================================================================
RCS file: /cvsroot/client/audiosvc/pub/hxaudply.h,v
retrieving revision 1.21.78.1
diff -u -r1.21.78.1 hxaudply.h
--- hxaudply.h	18 Sep 2009 04:45:12 -0000	1.21.78.1
+++ hxaudply.h	31 Aug 2010 16:40:29 -0000
@@ -55,6 +55,9 @@
 #include "hxplayvelocity.h"
 #include "hxslist.h"
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxTimelineLimit.h"
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
 // forward decls
 struct IHXAudioPlayerResponse;
 struct IHXAudioStream;
@@ -65,10 +68,6 @@
 struct IHXPreferences;
 struct IHXAudioCrossFade;
 
-#if defined(HELIX_FEATURE_POWER_SAVE)
-_INTERFACE IHXPowerSave;
-#endif // HELIX_FEATURE_POWER_SAVE
-
 typedef struct _HXAudioFormat HXAudioFormat;
 
 class CHXAudioSession;
@@ -99,6 +98,7 @@
 #endif 
 #ifdef HELIX_FEATURE_POWER_SAVE
 		      public IHXPowerSave,
+			  public IHXTimeLineLimit,
 #endif
 		      public IHXAudioCrossFade,
 		      public IHXCallback,
@@ -163,7 +163,8 @@
     
 #if defined(HELIX_FEATURE_POWER_SAVE)
     HXBOOL          m_bInPowerSave;         // Player in power save mode
-    IHXPowerSave*   m_pRendererPowerSave;
+    IHXPowerSave*   m_pPowerSave;
+    UINT32          m_ulLimitInMs;
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
   protected:
@@ -227,15 +228,22 @@
         
 #endif        
 
+protected:
+        void ApplyTimeLineLimit();
+public:	
 #if defined(HELIX_FEATURE_POWER_SAVE)
-    HX_RESULT RetrieveRendererPowerSave();
+	/*Implement IHXTimeLineLimit*/
+    STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs );
+    STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs );
+    STDMETHOD(ResetLimit) (THIS);
+    HX_RESULT RetrievePowerSave();
     /* IHXPowerSave methods */
     STDMETHOD_(HX_RESULT,StartPowerSave)                  ( THIS );
     STDMETHOD_(HX_RESULT,EndPowerSave)                    ( THIS );
     STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
     STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
     STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
-    STDMETHOD_(ULONG32,SetWakeUpInterval)      ( THIS_ ULONG32 /*IN*/ ulWakeUpInterval );
+    STDMETHOD(SetWakeUpInterval)      ( THIS_ ULONG32 ulWakeUpInterval );
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
 ---------------------------------------------------------------------------------------------------------------
 
 Index: hxaudply.cpp
 ===================================================================
 RCS file: /cvsroot/client/audiosvc/hxaudply.cpp,v
 retrieving revision 1.58.12.1
 diff -u -r1.58.12.1 hxaudply.cpp
 --- hxaudply.cpp	18 Sep 2009 04:45:11 -0000	1.58.12.1
 +++ hxaudply.cpp	31 Aug 2010 16:59:36 -0000
 @@ -152,8 +152,9 @@
  ,       m_pLastMappingStream(NULL)
  ,       m_bNewMapStarting(TRUE)    
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -,	    m_bInPowerSave(FALSE)
 -,       m_pRendererPowerSave(NULL)
 +,       m_bInPowerSave(FALSE)
 +,       m_pPowerSave(NULL)
 +,       m_ulLimitInMs(0)
  #endif /*HELIX_FEATURE_POWER_SAVE*/
  {
  #ifdef HELIX_FEATURE_VOLUME
 @@ -253,13 +254,13 @@
      // Delete the inactive clock source queue
      HX_DELETE(m_pInactiveClockSourceQueue);
  
 -    
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -        if(m_pRendererPowerSave)
 -        {
 -            HX_RELEASE(m_pRendererPowerSave);
 -        }
 +    if(m_pPowerSave)
 +    {
 +    	HX_RELEASE(m_pPowerSave);
 +    }
  #endif    
 +
  }
  
  /////////////////////////////////////////////////////////////////////////
 @@ -287,6 +288,9 @@
              , { GET_IIDHANDLE(IID_IHXPlaybackVelocity), (IHXPlaybackVelocity*)this }
  #endif /* #if defined(HELIX_FEATURE_PLAYBACK_VELOCITY) */
              , { GET_IIDHANDLE(IID_IHXClockSourceManager), (IHXClockSourceManager*) this }
 +#if defined(HELIX_FEATURE_POWER_SAVE)
 +            ,{ GET_IIDHANDLE(IID_IHXTimeLineLimit), (IHXTimeLineLimit*) this}
 +#endif
          };
  
      HX_RESULT res = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
 @@ -1482,6 +1486,7 @@
  	{
              theErr = m_Owner->Resume(this, bSessionRewindNeededForStream);
  	}
 +        ApplyTimeLineLimit();
      }
      else
      {
 @@ -1580,6 +1585,9 @@
          StopFakeTimeline();
      }
  
 +#if defined(HELIX_FEATURE_POWER_SAVE)
 +    EndPowerSave();
 +#endif    
      ResetPlayer();
  
      return HXR_OK;
 @@ -3020,41 +3028,64 @@
  }
  
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -HX_RESULT CHXAudioPlayer::RetrieveRendererPowerSave() {
 -    if (m_pRendererPowerSave != NULL)
 +HX_RESULT CHXAudioPlayer::RetrievePowerSave() 
 +{
 +    HX_RESULT retVal = HXR_FAIL;
 +	
 +    if (m_pPowerSave)
      {
 -        return HXR_OK;
 +	    retVal = HXR_OK;
      }
 -
 -    if (m_pActiveClockSource != NULL &&
 -        (m_pActiveClockSource->QueryInterface(IID_IHXPowerSave, (void**) &m_pRendererPowerSave) == HXR_OK))
 +    else
      {
 -        return HXR_OK;
 +        if (m_pActiveClockSource != NULL )
 +        {    
 +	        if (m_pActiveClockSource->QueryInterface(IID_IHXPowerSave, (void**) &m_pPowerSave) == HXR_OK)
 +            {
 +                retVal = HXR_OK;
 +            }
 +        }
 +        else 
 +        {
 +            if(m_Owner)
 +            { //device powersave
 +	              IHXAudioDevice * pAudioDev = NULL;
 +	              m_Owner->QueryInterface(IID_IHXAudioDevice, (void**) &pAudioDev);
 +	            
 +                if(pAudioDev)
 +                {
 +                    if (pAudioDev->QueryInterface(IID_IHXPowerSave, (void**) &m_pPowerSave) == HXR_OK)
 +                    {
 +                        retVal = HXR_OK;
 +                    }
 +                    HX_RELEASE(pAudioDev);
 +                }
 +            }
 +        }
      }
 -
 -    m_pRendererPowerSave = NULL;
 -    return HXR_FAIL;
 +	
 +    return retVal;
  }
  
  /* IHXPowerSave methods */
  STDMETHODIMP CHXAudioPlayer::StartPowerSave (void)
  {
      HX_RESULT theErr = HXR_FAIL;
 +	
      if (IsInPowerSave())
      {
 -        return HXR_FAIL;
 +        theErr =  HXR_ALREADY_INITIALIZED;
      }
 -
 -    if (!CanStartPowerSave())
 -    {
 -        return HXR_FAIL;
 -    }
 -
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    else
      {
 -        theErr = m_pRendererPowerSave->StartPowerSave();
 +        if (CanStartPowerSave())
 +        {
 +            if (RetrievePowerSave() == HXR_OK)
 +            {
 +                theErr = m_pPowerSave->StartPowerSave();
 +            }     
 +        }
      }
 -
      if (theErr == HXR_OK)
      {
          m_bInPowerSave = TRUE;
 @@ -3066,21 +3097,20 @@
  STDMETHODIMP CHXAudioPlayer::EndPowerSave (void)
  {
      HX_RESULT theErr = HXR_FAIL;
 -    if (!IsInPowerSave())
 -    {
 -        return HXR_FAIL;
 -    }
 -
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +	
 +    if (IsInPowerSave())
      {
 -        theErr = m_pRendererPowerSave->EndPowerSave();
 +        if (RetrievePowerSave() == HXR_OK)
 +        {
 +	        theErr = m_pPowerSave->EndPowerSave();
 +        }
      }
 -
      if (theErr == HXR_OK)
      {
          m_bInPowerSave = FALSE;
 -        m_pRendererPowerSave = NULL;
      }
 +    HX_RELEASE(m_pPowerSave);
 +
      return theErr;
  }
  
 @@ -3091,33 +3121,106 @@
  
  STDMETHODIMP_(HXBOOL) CHXAudioPlayer::CanStartPowerSave (void)
  {
 -    if (m_bHasStreams)
 -    {
 -        return FALSE;
 -    }
 +    HXBOOL retVal = FALSE;
  
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    if (RetrievePowerSave() == HXR_OK)
      {
 -        return m_pRendererPowerSave->CanStartPowerSave();
 +        retVal = m_pPowerSave->CanStartPowerSave();
      }
  
 -    return FALSE;
 +    return retVal;
  }
  
  STDMETHODIMP_(ULONG32) CHXAudioPlayer::GetWakeUpInterval (void)
  {
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    if (RetrievePowerSave() == HXR_OK)
      {
 -        return m_pRendererPowerSave->GetWakeUpInterval();
 +        return m_pPowerSave->GetWakeUpInterval();
      }
 +    return 0;
 +}
 +
 +STDMETHODIMP CHXAudioPlayer::SetWakeUpInterval (ULONG32  ulWakeUpInterval)
 +{
 +    HX_RESULT retVal = HXR_FAIL;
 +	if (RetrievePowerSave() == HXR_OK)
 +    {
 +        retVal = m_pPowerSave->SetWakeUpInterval(ulWakeUpInterval);
 +    }
 +	
 +	return retVal;
 +}
 +#endif
 +void CHXAudioPlayer::ApplyTimeLineLimit()
 +{
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +    UINT32 ulLimitInMs = 0;
 +
 +    ulLimitInMs = m_ulLimitInMs - m_ulAPstartTime + m_ulADresumeTime;
 +    HXLOGL2(HXLOG_ADEV, "CHXAudioPlayer[%p]::ApplyTimeLineLimit ulLimitInMs:%lu ", this, ulLimitInMs);
 +    
 +    if(m_Owner)
 +    { // Set audio session timelinelimit
 +        IHXTimeLineLimit* pTimeLineLimit = NULL;
 +        m_Owner->QueryInterface(IID_IHXTimeLineLimit, (void**) & pTimeLineLimit);
 +        if(pTimeLineLimit != NULL)
 +        {
 +            UINT32 ulDevLimitInMs = pTimeLineLimit->SetLimit(ulLimitInMs );
 +            HX_RELEASE(pTimeLineLimit);
 +        }
 +    } // End of if(m_Owner)
 +#endif
 +}
 +
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +STDMETHODIMP 
 +CHXAudioPlayer::SetLimit (UINT32 ulLimitInMs )
 +{
 +    HXLOGL2(HXLOG_ADEV, "CHXAudioPlayer[%p]::SetLimit ulLimitInMs:%lu ", this, ulLimitInMs);
 +    //  Store the limit (Presentation duration)
 +    //  Should be applied on audio session during resume
 +    //  after adjusting the start time
 +    m_ulLimitInMs = ulLimitInMs;
 +
 +    return HXR_OK;
  }
  
 -STDMETHODIMP_(ULONG32) CHXAudioPlayer::SetWakeUpInterval (ULONG32 /*IN*/ ulWakeUpInterval)
 +STDMETHODIMP 
 +CHXAudioPlayer::GetLimit (UINT32 &ulLimitInMs )
  {
 -    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
 +    HX_RESULT retVal = HXR_FAIL;
 +
 +    HXLOGL2(HXLOG_ADEV, "CHXAudioPlayer[%p]::GetLimit m_ulLimitInMs:%lu m_ulAPstartTime:%lu", this, m_ulLimitInMs, m_ulAPstartTime);
 +
 +    if(m_ulLimitInMs > 0)
      {
 -        return m_pRendererPowerSave->SetWakeUpInterval(ulWakeUpInterval);
 +        ulLimitInMs = m_ulLimitInMs - m_ulAPstartTime + m_ulADresumeTime;
 +        retVal = HXR_OK;
      }
 +
 +    return retVal;
  }
  
 +STDMETHODIMP 
 +CHXAudioPlayer::ResetLimit()
 +{
 +    HX_RESULT retVal = HXR_OK;
 +
 +    m_ulLimitInMs = 0;
 +
 +    if(m_Owner)
 +    {
 +        IHXTimeLineLimit* pTimeLineLimit = NULL;
 +        m_Owner->QueryInterface(IID_IHXTimeLineLimit, (void**) & pTimeLineLimit);
 +        if(pTimeLineLimit != NULL)
 +        {
 +            retVal = pTimeLineLimit->ResetLimit();
 +            HX_RELEASE(pTimeLineLimit);
 +        }
 +    } // End of if(m_Owner)
 +
 +    HXLOGL3(HXLOG_CORE, "CHXAudioPlayer[%p]::ResetLimit retVal:%x ", this, retVal);
 +    return retVal;
 +
 +}
  #endif /*HELIX_FEATURE_POWER_SAVE*/

 
---------------------------------------------------------------------------------------------------------------

Index: hxaudses.h
===================================================================
RCS file: /cvsroot/client/audiosvc/pub/hxaudses.h,v
retrieving revision 1.33.8.1
diff -u -r1.33.8.1 hxaudses.h
--- hxaudses.h	18 Sep 2009 04:45:12 -0000	1.33.8.1
+++ hxaudses.h	31 Aug 2010 17:04:08 -0000
@@ -58,6 +58,10 @@
 #include 
 #endif
 #include "hxcore.h"
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxTimelineLimit.h"
+#include  "hxPowerSave.h"
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
 //  IHXTimelineWatcher defines.
 #  define TLW_PAUSE    1
 #  define TLW_RESUME   2
@@ -116,10 +120,6 @@
 struct IHXAudioHook;
 struct IHXInterruptState;
 
-#if defined(HELIX_FEATURE_POWER_SAVE)
-_INTERFACE IHXPowerSave;
-#endif // HELIX_FEATURE_POWER_SAVE
-
 typedef struct _HXAudioFormat HXAudioFormat;
 class CHXAudioPlayer;
 
@@ -151,7 +151,8 @@
     public IHXVolumeAdviseSink,
 #endif                          
 #ifdef HELIX_FEATURE_POWER_SAVE
-		      public IHXPowerSave,
+    public IHXPowerSave,
+    public IHXTimeLineLimit,
 #endif
     public IHXCallback,
     public IHXAudioResamplerManager,
@@ -328,7 +329,20 @@
                                          HXBOOL&     /*OUT*/    bChanged
                                          );
 
+protected:
+    void ApplyPushdownLimit(UINT16& ulPushdown);
+    void CreateAudDevInterfaces(IHXAudioDevice* pAudioDev);
+    void ReleaseAudDeviceInterfaces();
 #if defined(HELIX_FEATURE_POWER_SAVE)
+	HX_RESULT ComputePowerSaveModePushDown();
+	UINT32 UpdateLimit();
+    
+public:
+
+	/*Implement IHXTimeLineLimit*/
+	STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs );
+	STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs );
+	STDMETHOD(ResetLimit) (THIS);
     /* 
      * IHXPowerSave methods
      */
@@ -337,9 +351,9 @@
     STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
     STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
     STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
-    STDMETHOD_(ULONG32,SetWakeUpInterval)      ( THIS_ ULONG32 /*IN*/ ulWakeUpInterval );
+	STDMETHOD(SetWakeUpInterval  ) (THIS_ ULONG32 ulWakeUpInterval );
 #endif /*HELIX_FEATURE_POWER_SAVE*/
-
+public:
 
     /*
      *  IHXAudioDeviceManager2 methods
@@ -657,6 +671,11 @@
     HXBOOL                  m_bMute;                // the mute state
 #if defined(HELIX_FEATURE_POWER_SAVE)
     HXBOOL                  m_bInPowerSave;         // Player in power save mode
+    UINT32                  m_ulWakeUpInterval;
+    IHXPowerSave*           m_pPowerSave;  
+    IHXTimeLineLimit*       m_pTimeLineLimit;
+    UINT32                  m_ulLimitInMs; 
+    ULONG32                 m_ulPrePowerSavePushdown;
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
     /*

------------------------------------------------------------------------------------------------------------------

Index: hxaudses.cpp
===================================================================
RCS file: /cvsroot/client/audiosvc/hxaudses.cpp,v
retrieving revision 1.84.2.1.2.1
diff -u -r1.84.2.1.2.1 hxaudses.cpp
--- hxaudses.cpp	12 Jan 2010 08:37:46 -0000	1.84.2.1.2.1
+++ hxaudses.cpp	31 Aug 2010 17:19:08 -0000
@@ -233,6 +233,11 @@
     , m_bMute(FALSE)
 #if defined(HELIX_FEATURE_POWER_SAVE)
     , m_bInPowerSave(FALSE)
+    , m_ulWakeUpInterval(0)
+    , m_pPowerSave(NULL)
+    , m_pTimeLineLimit(NULL)
+    , m_ulLimitInMs (0)
+    , m_ulPrePowerSavePushdown(0)
 #endif /*HELIX_FEATURE_POWER_SAVE*/
     , m_dBufEndTime((double) 0.)
     , m_bDisableWrite(FALSE)
@@ -470,9 +475,22 @@
 #endif            
             { GET_IIDHANDLE(IID_IHXAudioPushdown2),      (IHXAudioPushdown2*)this       },
             { GET_IIDHANDLE(IID_IHXAudioDeviceHookManager), (IHXAudioDeviceHookManager*)this},
+#ifdef HELIX_FEATURE_POWER_SAVE
+            { GET_IIDHANDLE(IID_IHXTimeLineLimit), (IHXTimeLineLimit*)this },
+            { GET_IIDHANDLE(IID_IHXPowerSave), (IHXPowerSave*)this },
+#endif /*HELIX_FEATURE_POWER_SAVE*/
         };
 
-    return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
+    HX_RESULT retval = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
+
+#ifdef HELIX_FEATURE_POWER_SAVE
+    if (retval != HXR_OK && m_pCurrentAudioDev)
+    {
+        retval = m_pCurrentAudioDev->QueryInterface(riid, ppvObj);
+    }
+#endif
+
+    return retval; 
 }
 
 /////////////////////////////////////////////////////////////////////////
@@ -1243,6 +1261,7 @@
  */
 HX_RESULT CHXAudioSession::PlayAudio(UINT16 uNumBlocks)
 {
+    ApplyPushdownLimit(uNumBlocks);
     HXLOGL4(HXLOG_ADEV, "CHXAudioSession[%p]::PlayAudio(): %u blocks", this, uNumBlocks);
 
     HX_RESULT theErr = HXR_OK;
@@ -2073,6 +2092,7 @@
 
             m_pCurrentAudioDev = (IHXAudioDevice*) pAudioDev;
 
+            CreateAudDevInterfaces(pAudioDev);
             HXLOGL3(HXLOG_ADEV, "CHXAudioSession[%p]::CreateAudioDevice(): created [%p]", this, m_pCurrentAudioDev);
         }
         else
@@ -2097,6 +2117,7 @@
     _NotifyTimelineWatchers( TLW_CLOSE );
     HX_RELEASE(m_pCurrentAudioDev);
 
+    ReleaseAudDeviceInterfaces();
     m_bToBeReOpened = FALSE;
     if (m_pDeviceCallback && m_pDeviceCallback->PendingID())
     {
@@ -2633,11 +2654,13 @@
         m_pCurrentAudioDev->Close(TRUE);
         _NotifyTimelineWatchers( TLW_CLOSE );
         HX_RELEASE(m_pCurrentAudioDev);
+        ReleaseAudDeviceInterfaces();
     }
 
     m_pCurrentAudioDev = pAudioDevice;
     m_pCurrentAudioDev->AddRef();
 
+    CreateAudDevInterfaces(m_pCurrentAudioDev);
     m_pReplacedAudioDev = pAudioDevice;
     m_pReplacedAudioDev->AddRef();
 
@@ -2712,6 +2735,7 @@
         HX_RELEASE(m_pCurrentAudioDev);
     }
 
+    ReleaseAudDeviceInterfaces();
     HX_RELEASE(m_pReplacedAudioDev);
     m_bReplacedDev = FALSE;
 
@@ -4502,32 +4526,244 @@
     }
 }
 
+//
+//  CHXAudioSession::ApplyPushdownLimit
+//  Limits the pushdown value based on
+//  power save cfg
+//
+void CHXAudioSession::ApplyPushdownLimit(UINT16& ulPushdown)
+{
+    //  Reason to limit is to avoid the mixer from producing
+    //  dummy silence data at the end of the playback
+#ifdef HELIX_FEATURE_POWER_SAVE
+    if(m_bInPowerSave && m_ulLimitInMs > 0)
+    {
+        if( m_ulLimitInMs < ((m_ulBlocksWritten + ulPushdown) * m_dGranularity) )
+        {
+            // ulPushdown needs to update
+            ulPushdown = ((m_ulLimitInMs / m_dGranularity) - m_ulBlocksWritten);
+            // Adding a block to cover roundoff errors.
+            ulPushdown++;
+
+        }
+    } // End of if(m_bInPowerSave && m_ulLimitInMs > 0)
+#endif // End of #ifdef HELIX_FEATURE_POWER_SAVE
+}
+
+//
+//  CHXAudioSession::CreateAudDevInterfaces
+//  To create interfaces from audio device
+//
+void CHXAudioSession::CreateAudDevInterfaces(IHXAudioDevice* pAudioDev)
+{
+    ReleaseAudDeviceInterfaces();
+#ifdef HELIX_FEATURE_POWER_SAVE
+    if(pAudioDev != NULL)
+    {
+        pAudioDev->QueryInterface(IID_IHXPowerSave, (void**) &m_pPowerSave);
+        pAudioDev->QueryInterface(IID_IHXTimeLineLimit, (void**) &m_pTimeLineLimit);
+
+        if (m_pPowerSave==0 || m_pTimeLineLimit==0)
+        {
+            HXLOGL2(HXLOG_ADEV, "CHXAudioSession::CreateAudDevInterfaces:query m_pPowerSave or m_pTimeLineLimit return 0");
+        }
+
+    }
+#endif
+}
+
+//
+//  CHXAudioSession::ReleaseAudDeviceInterfaces
+//  releases interfaces created from audio device
+//
+void CHXAudioSession::ReleaseAudDeviceInterfaces()
+{
+#ifdef HELIX_FEATURE_POWER_SAVE
+    HX_RELEASE(m_pPowerSave);
+    HX_RELEASE(m_pTimeLineLimit);
+#endif
+}
+
+
 #if defined(HELIX_FEATURE_POWER_SAVE)
-/* IHXPowerSave methods */
-STDMETHODIMP_(HX_RESULT) CHXAudioSession::StartPowerSave (void)
+//
+//  CHXAudioSession::UpdateLimit
+//  Queries the limit from all players
+//  and uses the min for device and max for
+//  pushdown limit
+//
+UINT32 CHXAudioSession::UpdateLimit()
 {
-    HX_RESULT theErr = HXR_FAIL;
-    if (IsInPowerSave())
+    UINT32 ulLowestLimitInMs = MAX_UINT32;
+    UINT32 ulHighestLimitInMs = 0;
+    HX_RESULT rv = HXR_OK;
+
+    HXLOGL3(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): m_pPlayerList = %p", this, m_pPlayerList);
+    if(m_pPlayerList && m_pPlayerList->GetCount() > 0)
     {
-        return HXR_FAIL;
+
+        CHXAudioPlayer* pPlayer = NULL;
+        CHXSimpleList::Iterator lIter;
+        for (lIter = m_pPlayerList->Begin(); lIter != m_pPlayerList->End(); ++lIter)
+        {
+            IHXTimeLineLimit* pTimeLimit = NULL;
+            pPlayer = (CHXAudioPlayer*) (*lIter);
+            pPlayer->QueryInterface(IID_IHXTimeLineLimit, (void**) &pTimeLimit);
+            if(pTimeLimit)
+            {
+                UINT32 ulLimit = 0;
+                rv = pTimeLimit->GetLimit(ulLimit);
+                HXLOGL2(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): pTimeLimit:%p ulLimit:%lu", this, pTimeLimit, ulLimit);
+                HX_RELEASE(pTimeLimit);
+                if( (rv == HXR_NO_DATA) || (ulLimit == 0) )
+                {
+                    // Player is not interested in applying limit
+                    // break out
+                    ulLowestLimitInMs = 0;
+                    ulHighestLimitInMs = 0;
+                    break;
+                }
+                else
+                {
+                    if(ulLimit < ulLowestLimitInMs)
+                    {
+                        ulLowestLimitInMs = ulLimit;
+                    }
+
+                    if(ulLimit > ulHighestLimitInMs)
+                    {
+                        ulHighestLimitInMs = ulLimit;
+                    }
+                }
+            }
+            else
+            {
+                // One of the player is not interested in applying limit
+                // break out
+                ulLowestLimitInMs = 0;
+                ulHighestLimitInMs = 0;
+                HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): IHXTimeLineLimit NOT SUPPOPRTED", this);
+                break;
+            }
+
+        } // End of for (lIter = m_pPlayerList->Begin(); lIter != m_pPlayerList->End(); ++lIter)
+
+
+    } // End of if(m_pPlayerList && m_pPlayerList->GetCount() > 0)
+
+    HXLOGL2(HXLOG_CORE, "CHXAudioSession[%p]::UpdateLimit(): Hi:%lu Lo:%lu", this, ulHighestLimitInMs, ulLowestLimitInMs);
+    if( (ulHighestLimitInMs != 0) && (ulLowestLimitInMs != 0) )
+    {
+        // highest value is used for max pushdown calculation
+        // Typically this is the duration of the playback
+        // start time is already adjusted on this limit
+        m_ulLimitInMs = ulHighestLimitInMs;
+
+        //set dev from audply
+        if(m_pTimeLineLimit != NULL)
+        {
+            // Lowest is set on the device
+            m_pTimeLineLimit->SetLimit(ulLowestLimitInMs);
+        }
+    } // End of if( (ulHighestLimitInMs != 0) && (ulLowestLimitInMs != 0) )
+    return ulLowestLimitInMs;
+}
+
+HX_RESULT CHXAudioSession::ComputePowerSaveModePushDown()
+{
+    HX_RESULT retVal = HXR_OK;
+    if(m_ulWakeUpInterval != 0)
+    {
+        retVal = SetAudioPushdown(m_ulWakeUpInterval);
     }
+	return retVal;
+}
+STDMETHODIMP CHXAudioSession::SetLimit (UINT32 ulLimitInMs )
+{
+    UINT32 retVal = 0;
+    m_pMutex->Lock();
 
-    if (!CanStartPowerSave())
+    //  ulLimitInMs is ignored
+    //  limit values are queried from all audio players
+    //  this call is used for getting limits from
+    //  all audio players
+
+    if(m_bInPowerSave)
     {
-        return HXR_FAIL;
+        retVal = UpdateLimit();
+        HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::SetLimit(): m_ulLimitInMs[%lu] ", this, m_ulLimitInMs);
     }
 
+    m_pMutex->Unlock();
 
-    if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+    return retVal;
+}
+
+STDMETHODIMP CHXAudioSession::GetLimit (UINT32 &ulLimitInMs )
+{
+    HX_RESULT retVal = HXR_FAIL;
+
+    m_pMutex->Lock();
+
+    if(m_ulLimitInMs != 0)
     {
-        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
-        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        theErr = pPlayer->StartPowerSave();
+        ulLimitInMs = m_ulLimitInMs;
+        retVal = HXR_OK;
     }
 
-    if (theErr == HXR_OK)
+    HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::GetLimit(): retVal = %x ulLimitInMs[%lu] ", this, ulLimitInMs);
+
+    m_pMutex->Unlock();
+
+    return retVal;
+}
+
+STDMETHODIMP CHXAudioSession::ResetLimit ()
+{
+	m_pMutex->Lock();
+
+	m_ulLimitInMs = 0;
+
+	if(m_pTimeLineLimit)
+	{
+		m_pTimeLineLimit->ResetLimit();
+	}
+
+	HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::ResetLimit() ", this);
+
+	m_pMutex->Unlock();
+
+	return HXR_OK;
+}
+/* IHXPowerSave methods */
+STDMETHODIMP_(HX_RESULT) CHXAudioSession::StartPowerSave (void)
+{
+    HXLOGL2(HXLOG_ADEV, "CHXAudioSession[%p]::StartPowerSave() ");
+    HX_RESULT theErr = HXR_FAIL;
+	
+    if (IsInPowerSave())
     {
-        m_bInPowerSave = TRUE;
+        theErr =  HXR_ALREADY_INITIALIZED;
+    }
+    else
+    {
+        if (CanStartPowerSave())
+        {
+            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+            CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+            if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+            {
+                theErr = pPlayer->StartPowerSave();
+
+                if (theErr == HXR_OK)
+                {
+                    m_bInPowerSave = TRUE;
+                    m_ulWakeUpInterval = pPlayer->GetWakeUpInterval();
+                    m_ulPrePowerSavePushdown = m_ulTargetPushdown;
+                    ComputePowerSaveModePushDown();
+                }
+            }
+        }
     }
 
     return theErr;
@@ -4535,18 +4771,22 @@
 
 STDMETHODIMP_(HX_RESULT) CHXAudioSession::EndPowerSave (void)
 {
+    HXLOGL2(HXLOG_ADEV, "CHXAudioSession[%p]::EndPowerSave() ");
     HX_RESULT theErr = HXR_FAIL;
-    if (!IsInPowerSave())
+	
+    if (IsInPowerSave())
     {
-        return HXR_FAIL;
+        if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+        {
+            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+            CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+            theErr = pPlayer->EndPowerSave();
+            UINT32 ulMinimumPushdown = (m_ulMinimumStartupPushdownGetCount() == 1)
-    {
-        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
-        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        theErr = pPlayer->EndPowerSave();
-    }
 
     if (theErr == HXR_OK)
     {
@@ -4563,41 +4803,45 @@
 
 STDMETHODIMP_(HXBOOL) CHXAudioSession::CanStartPowerSave (void)
 {
-    if (m_bHasStreams)
-    {
-        return FALSE;
-    }
-
-    if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+    HXBOOL retVal = FALSE;
+	
+    if (m_pPlayerList )
     {
-        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
-        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        return pPlayer->CanStartPowerSave();
+        if (m_pPlayerList->GetCount() == 1)
+        {
+            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+            CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+            retVal = pPlayer->CanStartPowerSave();
+        }
     }
 
-    return FALSE;
+    return retVal;
 }
 
-STDMETHODIMP_(ULONG32) CHXAudioSession::GetWakeUpInterval (void)
+STDMETHODIMP_(ULONG32) CHXAudioSession::GetWakeUpInterval ()
 {
+    ULONG32 ulWakeUpInterval = 0;
+	
     if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
     {
         CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
         CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        return pPlayer->GetWakeUpInterval();
+        ulWakeUpInterval = pPlayer->GetWakeUpInterval();
     }
-    return 0;
+    HXLOGL1(HXLOG_CORE, "CHXAudioSession[%p]::GetWakeUpInterval(): ulWakeUpInterval = %lu ", ulWakeUpInterval);
+    return ulWakeUpInterval;
 }
 
-STDMETHODIMP_(ULONG32) CHXAudioSession::SetWakeUpInterval (ULONG32 /*IN*/ ulWakeUpInterval)
+STDMETHODIMP CHXAudioSession::SetWakeUpInterval(ULONG32 ulWakeUpInterval )
 {
+    HX_RESULT retVal = HXR_FAIL;
     if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
     {
         CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
         CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
-        return pPlayer->SetWakeUpInterval(ulWakeUpInterval);
+        retVal = pPlayer->SetWakeUpInterval(ulWakeUpInterval);
     }
-    return 0;
+    return retVal;
 }
 
 #endif /*HELIX_FEATURE_POWER_SAVE*/

 ---------------------------------------------------------------------------------------------------------------------
 
 Index: hxcleng.h
 ===================================================================
 RCS file: /cvsroot/client/core/pub/hxcleng.h,v
 retrieving revision 1.50.2.1
 diff -u -r1.50.2.1 hxcleng.h
 --- hxcleng.h	18 Sep 2009 04:46:03 -0000	1.50.2.1
 +++ hxcleng.h	31 Aug 2010 18:18:48 -0000
 @@ -76,6 +76,9 @@
  #define _MEDIUM_BLOCK 1
  #endif
  
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +#include  "hxPowerSave.h"
 +#endif /*HELIX_FEATURE_POWER_SAVE*/
  class	HXCommonClassFactory;
  class	HXScheduler;
  class   HXOptimizedSchedulerBase;
 @@ -137,10 +140,6 @@
  #endif
  #endif //HELIX_FEATURE_NETSERVICES
  
 -#if defined(HELIX_FEATURE_POWER_SAVE)
 -_INTERFACE IHXPowerSave;
 -#endif // HELIX_FEATURE_POWER_SAVE
 -
  #if defined(HELIX_FEATURE_SYSTEMREQUIRED)
  class HXSystemRequired : public IHXSystemRequired
  {
 @@ -624,7 +623,7 @@
      STDMETHOD_(HXBOOL,IsInPowerSave)           ( THIS );
      STDMETHOD_(HXBOOL,CanStartPowerSave)       ( THIS );
      STDMETHOD_(ULONG32,GetWakeUpInterval)      ( THIS );
 -    STDMETHOD_(ULONG32,SetWakeUpInterval)      ( THIS_ ULONG32 /*IN*/ ulWakeUpInterval );
 +    STDMETHOD(SetWakeUpInterval)               ( THIS_ ULONG32 ulWakeUpInterval );
  #endif /*HELIX_FEATURE_POWER_SAVE*/
  
  
 @@ -668,8 +667,9 @@
      HXTimeval*                    m_pCurrentTime;
  #endif /*HELIX_FEATURE_SYSTEM_EXTERNAL_TIMER*/
  #if defined(HELIX_FEATURE_POWER_SAVE)
 -    HXBOOL			m_bInPowerSave;
 -    ULONG32			m_ulWakeUpInterval;
 +    HXBOOL             m_bInPowerSave;
 +    HXBOOL             m_bPowerSaveModeAllowed;
 +    ULONG32            m_ulWakeUpInterval;
  #endif /*HELIX_FEATURE_POWER_SAVE*/
  
  };
 -------------------------------------------------------------------------------------------------------------
 
 Index: hxcleng.cpp
 ===================================================================
 RCS file: /cvsroot/client/core/hxcleng.cpp,v
 retrieving revision 1.136.8.1.2.1
 diff -u -r1.136.8.1.2.1 hxcleng.cpp
 --- hxcleng.cpp	28 Apr 2010 20:52:56 -0000	1.136.8.1.2.1
 +++ hxcleng.cpp	31 Aug 2010 18:27:17 -0000
 @@ -388,6 +388,7 @@
  
  ,m_pContext(NULL)
  #if defined(HELIX_FEATURE_POWER_SAVE)
 +,m_bPowerSaveModeAllowed(FALSE)
  ,m_bInPowerSave(FALSE)
  ,m_ulWakeUpInterval(DEFAULT_WAKEUP_INTERVAL)
  #endif /*HELIX_FEATURE_POWER_SAVE*/
 @@ -858,7 +859,12 @@
          ReadPrefBOOL(m_pPreferences, "UseCoreThread", m_bUseCoreThread);  
      }
  #endif /*_WIN32*/
 +#ifdef HELIX_FEATURE_POWER_SAVE
  
 +	ReadPrefBOOL(m_pPreferences, "EnablePowerSaveMode", m_bPowerSaveModeAllowed);
 +	HXLOGL1( HXLOG_CORE, "Preferences values are: m_bPowerSaveModeAllowed %d ", m_bPowerSaveModeAllowed );
 +
 +#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
      InitializeThreadedObjects();
  
  #if defined(HELIX_FEATURE_AUDIO)
 @@ -1024,7 +1030,9 @@
          { GET_IIDHANDLE(IID_IHXAutoBWCalibrationAdviseSink), (IHXAutoBWCalibrationAdviseSink*)this },
  	{ GET_IIDHANDLE(IID_IHXContextUser), (IHXContextUser*)this },
  // #ifdef..
 +#ifdef HELIX_FEATURE_POWER_SAVE
  	{ GET_IIDHANDLE(IID_IHXPowerSave), (IHXPowerSave*)this }
 +#endif /*HELIX_FEATURE_POWER_SAVE*/
      };
      HX_RESULT retval = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
      if (retval == HXR_OK)
 @@ -2629,6 +2637,13 @@
   const char* pMoreInfoURL
   )
  {
 +#ifdef HELIX_FEATURE_POWER_SAVE
 +    if (unSeverity != HXLOG_DEBUG   &&
 +        ulHXCode  != HXR_OK)
 +    {
 +        EndPowerSave();
 +    }
 +#endif
      if (m_PlayerList.GetCount())
      {
          HXPlayer* pHXPlayer = (HXPlayer*)m_PlayerList.GetTail();
 @@ -3036,25 +3051,32 @@
  #if defined(HELIX_FEATURE_POWER_SAVE)
  STDMETHODIMP_(HX_RESULT) HXClientEngine::StartPowerSave(void)
  {
 -    HX_RESULT theErr = HXR_OK;
 +    HX_RESULT theErr = HXR_FAIL;
 +    HXLOGL2( HXLOG_CORE, "HXClientEngine[%p]::StartPowerSave m_bPowerSaveModeAllowed:%d m_bInPowerSave:%d", this, m_bPowerSaveModeAllowed, m_bInPowerSave);
  
 -    if (!CanStartPowerSave())
 +    if (m_pCoreMutex)
      {
 -        return HXR_FAIL;
 +        m_pCoreMutex->Lock();
      }
 -
 -    if (m_pAudioSession)
 +    if (CanStartPowerSave())
      {
 -        m_ulWakeUpInterval = m_pAudioSession->SetWakeUpInterval(m_ulWakeUpInterval);
 -        theErr = m_pAudioSession->StartPowerSave();
 -
 -        /* Add the interval to HXPlayer */
 -        HX_ASSERT(GetPlayerCount() == 1);
 -
 -        HXPlayer* pPlayer = m_PlayerList.GetHead();
 -        if (pPlayer != NULL)
 +        if (m_pAudioSession)
          {
 -            pPlayer->AdjustWakeUpInterval(m_ulWakeUpInterval);
 +            m_pAudioSession->SetWakeUpInterval(m_ulWakeUpInterval);
 +            m_ulWakeUpInterval = m_pAudioSession->GetWakeUpInterval();
 +            theErr = m_pAudioSession->StartPowerSave();
 +
 +            /* Add the interval to HXPlayer */
 +            HX_ASSERT(GetPlayerCount() == 1);
 +            LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
 +            if (lPosition != NULL)
 +            {
 +                HXPlayer* pPlayer = (HXPlayer*) m_PlayerList.GetAt(lPosition);
 +                if (pPlayer != NULL)
 +                {
 +                    pPlayer->AdjustWakeUpInterval(m_ulWakeUpInterval);
 +                }
 +            }
          }
      }
  
 @@ -3067,27 +3089,39 @@
          EndPowerSave();
      }
  
 +    if (m_pCoreMutex)
 +    {
 +        m_pCoreMutex->Unlock();
 +    }
      return theErr;
  }
  
  STDMETHODIMP_(HX_RESULT) HXClientEngine::EndPowerSave(void)
  {
 -    HX_RESULT theErr = HXR_OK;
 -
 -    if (!IsInPowerSave())
 +   HXLOGL2( HXLOG_CORE, "HXClientEngine[%p]::EndPowerSave m_bPowerSaveModeAllowed:%d m_bInPowerSave:%d", this, m_bPowerSaveModeAllowed, m_bInPowerSave);
 +    HX_RESULT theErr = HXR_FAIL;
 +    if (m_pCoreMutex)
      {
 -        return HXR_FAIL;
 +        m_pCoreMutex->Lock();
      }
  
 -    if (m_pAudioSession)
 +    if (IsInPowerSave())
      {
 -        theErr = m_pAudioSession->EndPowerSave();
 +        if (m_pAudioSession)
 +        {
 +            theErr = m_pAudioSession->EndPowerSave();
 +        }
      }
  
      if (theErr == HXR_OK)
      {
          m_bInPowerSave = FALSE;
      }
 +	
 +    if (m_pCoreMutex)
 +    {
 +        m_pCoreMutex->Unlock();
 +    }
  
      return theErr;
  }
 @@ -3099,39 +3133,38 @@
  
  STDMETHODIMP_(HXBOOL) HXClientEngine::CanStartPowerSave(void)
  {
 -    if ((GetPlayerCount() > 1) || m_bInPowerSave)
 +    HXBOOL retVal = FALSE;
 +    if ((GetPlayerCount() == 1)&& !m_bInPowerSave && m_bPowerSaveModeAllowed)
      {
 -        return FALSE;
 -    }
 -
 -    LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
 -    if (lPosition != NULL)
 -    {
 -        HXPlayer* pPlayer = (HXPlayer*) m_PlayerList.GetAt(lPosition);
 -        if (pPlayer != NULL && !pPlayer->IsLocalSource())
 +        LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
 +        if (lPosition != NULL)
          {
 -            return FALSE;
 +            HXPlayer* pPlayer = (HXPlayer*) m_PlayerList.GetAt(lPosition);
 +            if (pPlayer && pPlayer->IsPowerSaveCapable()) 
 +            {
 +                if (m_pAudioSession)
 +                {
 +                    retVal = m_pAudioSession->CanStartPowerSave();
 +                }
 +            }     
          }
      }
  
 -    if (m_pAudioSession)
 -    {
 -        return m_pAudioSession->CanStartPowerSave();
 -    }
  
 -    return FALSE;
 +    return retVal;
  }
  
  STDMETHODIMP_(ULONG32) HXClientEngine::GetWakeUpInterval(void)
  {
 +    HXLOGL2( HXLOG_CORE, "HXClientEngine[%p]::GetWakeUpInterval  m_ulWakeUpInterval: %lu ",m_ulWakeUpInterval);
      return m_ulWakeUpInterval;
  }
  
 -STDMETHODIMP_(ULONG32) HXClientEngine::SetWakeUpInterval( ULONG32 /*IN*/ ulWakeUpInterval)
 +STDMETHODIMP HXClientEngine::SetWakeUpInterval( ULONG32  ulWakeUpInterval)
  {
      m_ulWakeUpInterval = ulWakeUpInterval;
  
 -    return m_ulWakeUpInterval;
 +    return HXR_OK;
  }
  
  #endif /*HELIX_FEATURE_POWER_SAVE*/
 

--------------------------------------------------------------------------------------------------------------------

Index: hxplay.h
===================================================================
RCS file: /cvsroot/client/core/pub/hxplay.h,v
retrieving revision 1.69.8.1
diff -u -r1.69.8.1 hxplay.h
--- hxplay.h	18 Sep 2009 04:46:03 -0000	1.69.8.1
+++ hxplay.h	31 Aug 2010 18:31:25 -0000
@@ -218,7 +218,9 @@
 /* Lowest allowable time sync granularity */
 #define MINIMUM_TIMESYNC_GRANULARITY	20
 
+
 #define DEFAULT_WAKEUP_INTERVAL		100
+
 #ifndef _WIN16
 //#if defined(HELIX_FEATURE_AUTHENTICATION)
 typedef WRAPPED_POINTER(IUnknown) Wrapped_IUnknown;
@@ -1649,13 +1651,15 @@
     {
         m_ulPlayerWakeUpInterval = ulWakeUpInterval;
     }
+    HXBOOL IsPowerSaveCapable();
+    HX_RESULT UpdatePowerSaveLimit();
 #endif /*HELIX_FEATURE_POWER_SAVE*/
 
     /* Examine all sources in the player.  If any source is a network 
        source (HXNetSource), it will fail.  If any source is a file 
        source (HXFileSource) and either a file or file format object 
        report NETWORKACCESS, it will fail. */
-    HXBOOL IsLocalSource();
+
 
     ////////////////////////////////////////////////////////////////////
     //
@@ -2252,6 +2256,7 @@
     IHXRecordService*	        m_pRecordService;
     HXBOOL                      m_bRecordServiceEnabled;
 
+    IHXScheduler3*              m_pScheduler3;
 #if defined(HELIX_FEATURE_POWER_SAVE)
     ULONG32                     m_ulPlayerWakeUpInterval;
 #endif

------------------------------------------------------------------------------------------------------------
Index: hxplay.cpp
===================================================================
RCS file: /cvsroot/client/core/hxplay.cpp,v
retrieving revision 1.200.8.1.2.1
diff -u -r1.200.8.1.2.1 hxplay.cpp
--- hxplay.cpp	9 Nov 2009 09:22:52 -0000	1.200.8.1.2.1
+++ hxplay.cpp	31 Aug 2010 18:36:40 -0000
@@ -430,6 +430,7 @@
     ,m_pSharedWallClocks(NULL)
     ,m_pRecordService(NULL)
     ,m_bRecordServiceEnabled(FALSE)
+    , m_pScheduler3(NULL)
 #if defined(HELIX_FEATURE_POWER_SAVE)
     ,m_ulPlayerWakeUpInterval(0)
 #endif //HELIX_FEATURE_POWER_SAVE
@@ -1673,6 +1674,11 @@
     CreateInstanceCCF(CLSID_IHXUpgradeCollection, (void**)&m_pUpgradeCollection, (IUnknown*)(IHXClientEngine*)m_pEngine);  
 #endif /* HELIX_FEATURE_AUTOUPGRADE */
 
+    HX_RELEASE(m_pScheduler3);
+    m_pScheduler->QueryInterface(IID_IHXScheduler3, (void**)&m_pScheduler3);
+
+    HXLOGL4( HXLOG_CORE, "HXPlayer::m_pScheduler3[%p]", m_pScheduler3);
+
     return theErr;
 }
 
@@ -6605,6 +6611,8 @@
     HX_RELEASE (m_pRegistry);
 #endif /* HELIX_FEATURE_REGISTRY */
 
+    HX_RELEASE(m_pScheduler3);
+
     HX_RELEASE (m_pEngine);
     HX_RELEASE (m_pClient);
     HX_RELEASE (m_pScheduler);
@@ -9590,7 +9598,10 @@
     {
         m_pAdviseSink->OnPosLength(m_ulCurrentPlayTime, m_ulPresentationDuration);
     }
+#ifdef HELIX_FEATURE_POWER_SAVE
 
+    UpdatePowerSaveLimit();
+#endif /*HELIX_FEATURE_POWER_SAVE*/
     return;
 }
 
@@ -11402,14 +11413,13 @@
 #endif  // _MACINTOSH
 
 #if defined(HELIX_FEATURE_POWER_SAVE) && defined(HELIX_FEATURE_AUDIO)
-    if (m_pAudioPlayer && m_pAudioPlayer->IsInPowerSave())
+    if (m_pAudioPlayer && m_pScheduler3 
+            && !m_pScheduler3->IsPaused()&& m_pAudioPlayer->IsInPowerSave())
     {
         // the actually interval from device may differ slightly from set from user (due to some alignment).
         // todo, do we need get this interval each time? 
         // is there possiblity that the interval modified from render/device unpredictably?
-        m_ulPlayerWakeUpInterval = m_pAudioPlayer->GetWakeUpInterval();
-        if (ulRet < m_ulPlayerWakeUpInterval)
-            ulRet = m_ulPlayerWakeUpInterval;//FIXME-Y
+        ulRet += m_ulPlayerWakeUpInterval;
     }
 #endif // (HELIX_FEATURE_POWER_SAVE) && (HELIX_FEATURE_AUDIO)
 
@@ -13958,22 +13968,33 @@
     }
 }
 
-HXBOOL HXPlayer::IsLocalSource()
+#ifdef HELIX_FEATURE_POWER_SAVE
+HX_RESULT HXPlayer::UpdatePowerSaveLimit()
 {
-    CHXMapPtrToPtr::Iterator iter = m_pSourceMap->Begin();
-    while(iter != m_pSourceMap->End())
+    HX_RESULT retVal = HXR_FAIL;
+    if(m_pAudioPlayer)
     {
-        SourceInfo* pSourceInfo = (SourceInfo*)(*iter);
-        HX_ASSERT (pSourceInfo != NULL);
+        HXLOGL1( HXLOG_CORE, "HXPlayer[%p]::UpdatePowerSaveLimit Limit:%lu", this, m_ulPresentationDuration);
+        retVal = m_pAudioPlayer->SetLimit (m_ulPresentationDuration);
+    }
+    return retVal;
+}
+
+HXBOOL HXPlayer::IsPowerSaveCapable()
+{
+    HXBOOL bPowerSaveCapable = FALSE;
+    if((m_pSourceMap != NULL) &&
+        (m_pSourceMap->GetCount() == 1) )
+    {
+        CHXMapPtrToPtr::Iterator    ndxSource;
+        ndxSource = m_pSourceMap->Begin();
+        SourceInfo* pSourceInfo = (SourceInfo*) (*ndxSource);
         HXSource* pSource = pSourceInfo->m_pSource;
-        if (pSource != NULL)
+        if(pSource && !(pSource->UsesNetworkAccess()))
         {
-            if (((HXSource*)pSource)->UsesNetworkAccess())
-            {
-                return FALSE;
-            }
+            bPowerSaveCapable = TRUE;
         }
-        ++iter;
-    }
-    return TRUE;
+    } 
+    return bPowerSaveCapable;
 }
+#endif /*HELIX_FEATURE_POWER_SAVE*/

--------------------------------------------------------------------------------------------------------

Index: chxmedpltfmsched.h
===================================================================
RCS file: /cvsroot/client/medpltfm/pub/chxmedpltfmsched.h,v
retrieving revision 1.7
diff -u -r1.7 chxmedpltfmsched.h
--- chxmedpltfmsched.h	6 Jul 2007 21:58:21 -0000	1.7
+++ chxmedpltfmsched.h	31 Aug 2010 18:47:47 -0000
@@ -57,8 +57,9 @@
 class CHXMediaPlatformKicker;
 
 class CHXMediaPlatformScheduler : public CUnknownIMP
-				, public IHXScheduler
-				, public IHXScheduler2
+                , public IHXScheduler
+                , public IHXScheduler2
+                , public IHXScheduler3
 {
 protected:
     UINT32			m_ulThreadID;
@@ -114,6 +115,9 @@
 						    ULONG32 ulTimeout);
     STDMETHOD_(ULONG32, GetThreadID)		    (THIS);
     STDMETHOD_(HXBOOL, AreImmediatesPending)	    (THIS);
+    STDMETHOD(PauseScheduler)   (THIS_);    
+    STDMETHOD(ResumeScheduler)  (THIS_);
+    STDMETHOD_(HXBOOL, IsPaused)  (THIS_);
 
     HX_RESULT	Init(IUnknown* pContext);
     HX_RESULT	AttachKicker(CHXMediaPlatformKicker* pKicker);

------------------------------------------------------------------------------------------------------------

Index: chxmedpltfmsched.cpp
===================================================================
RCS file: /cvsroot/client/medpltfm/chxmedpltfmsched.cpp,v
retrieving revision 1.8
diff -u -r1.8 chxmedpltfmsched.cpp
--- chxmedpltfmsched.cpp	6 Jul 2007 21:58:19 -0000	1.8
+++ chxmedpltfmsched.cpp	12 Aug 2010 22:15:54 -0000
@@ -60,6 +60,7 @@
 BEGIN_INTERFACE_LIST_NOCREATE(CHXMediaPlatformScheduler)
     INTERFACE_LIST_ENTRY_SIMPLE(IHXScheduler)
     INTERFACE_LIST_ENTRY_SIMPLE(IHXScheduler2)
+    INTERFACE_LIST_ENTRY_SIMPLE(IHXScheduler3)
     INTERFACE_LIST_ENTRY_DELEGATE(IID_IHXMutex, _InternalQIMutex)
 END_INTERFACE_LIST
 
@@ -213,6 +214,24 @@
     return m_pScheduler ? m_pScheduler->AreImmediatesPending() : FALSE; 
 }
 
+STDMETHODIMP
+CHXMediaPlatformScheduler::PauseScheduler()
+{
+    return m_pScheduler ? m_pScheduler->PauseScheduler() : HXR_FAILED;
+}
+
+STDMETHODIMP
+CHXMediaPlatformScheduler::ResumeScheduler()
+{
+    return m_pScheduler ? m_pScheduler->ResumeScheduler() : HXR_FAILED;
+}
+
+STDMETHODIMP_(HXBOOL)
+CHXMediaPlatformScheduler::IsPaused(void)
+{
+    return m_pScheduler ? m_pScheduler->IsPaused() : FALSE; 
+}
+
 HX_RESULT
 CHXMediaPlatformScheduler::_InternalQIMutex(REFIID riid, void** ppvObj)
 {

------------------------------------------------------------------------------------------------------------
Index: chxmedpltfm.cpp
===================================================================
RCS file: /cvsroot/client/medpltfm/chxmedpltfm.cpp,v
retrieving revision 1.78.4.3
diff -u -r1.78.4.3 chxmedpltfm.cpp
--- chxmedpltfm.cpp	7 Jul 2010 23:21:52 -0000	1.78.4.3
+++ chxmedpltfm.cpp	9 Aug 2010 16:27:22 -0000
@@ -1141,8 +1141,9 @@
         {
             rc = m_pMutex ? m_pMutex->QueryInterface(riid, ppvObj) : HXR_NOTIMPL;
         }
-        else if ((IsEqualIID(riid, IID_IHXScheduler) ||
-                  IsEqualIID(riid, IID_IHXScheduler2)))
+        else if (IsEqualIID(riid, IID_IHXScheduler) ||
+                  IsEqualIID(riid, IID_IHXScheduler2)||
+                  IsEqualIID(riid, IID_IHXScheduler3))
         {
             rc = m_pScheduler ? m_pScheduler->QueryInterface(riid, ppvObj) : HXR_NOTIMPL;
         }


---------------------------------------------------------------------------------------------------------------

Index: R1_Mobile_4_0_Factory.cfg
===================================================================
RCS file: /cvsroot/clientapps/symbiancommon/config/R1_Mobile_4_0_Factory.cfg,v
retrieving revision 1.57.4.5
diff -u -r1.57.4.5 R1_Mobile_4_0_Factory.cfg
--- R1_Mobile_4_0_Factory.cfg	17 Jun 2010 12:37:53 -0000	1.57.4.5
+++ R1_Mobile_4_0_Factory.cfg	26 Aug 2010 15:59:46 -0000
@@ -62,7 +62,7 @@
 LinkChar-MTD=2000
 BaseAdaptationTargetTime=5000
 UseCMMFHWDeviceAudioCodec=0
-UseWMACMMFHWDeviceAudioCodec=0
+UseWMACMMFHWDeviceAudioCodec=1
 MetaDataKeys=Title,Copyright,Author,Abstract,Genre,Performer,Album,Tracknumber,WM/AlbumTitle,WM/Year,WM/Text,WM/TrackNumber,WM/Genre,WM/Composer,WM/OriginalArtist,WM/Picture,WM/AudioFileURL,WM/Provider
 #Partial PlayBack values
 DisablePartialPlayback=0
@@ -155,3 +155,6 @@
 UDPFirewallKnock=1
 # Maximum preroll supported for local playback
 MaxVideoPreroll=4000
+
+# For Power Save feature with AudioController
+EnablePowerSaveMode=1

------------------------------------------------------------------------------------------------------------------

Index: hxmmfstatectrl.h
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/hxmmfstatectrl.h,v
retrieving revision 1.19.12.8
diff -u -r1.19.12.8 hxmmfstatectrl.h
--- hxmmfstatectrl.h	12 May 2010 19:27:56 -0000	1.19.12.8
+++ hxmmfstatectrl.h	24 Aug 2010 20:12:53 -0000
@@ -74,6 +74,9 @@
 #define HXR_SEND_BUFFER_START                     0x1
 #define HXR_SEND_BUFFER_COMPLETE                  0x2
 #define HXR_SEND_BUFFER_UNKNOWN                   0x4
+#ifdef HELIX_FEATURE_POWER_SAVE
+#include  "hxPowerSave.h"
+#endif /*ifdef HELIX_FEATURE_POWER_SAVE*/
 
 #define POST_SEEK_TIMER_VALUE  5000*1000  //5 seconds
 
@@ -182,6 +185,8 @@
     virtual HX_RESULT StepFrames(TInt aStep);
 #endif
 
+    void StartPowerSave();
+    void EndPowerSave();
   protected:
     HXMMFPlayCtrl*        m_pPlayerControl;
     HXMMFState*           m_pCurrentState;
@@ -261,6 +266,11 @@
     UINT8     m_bufferStatus;
     HXBOOL    m_bVideoController;
     TThreadId m_clientTid;
+#ifdef HELIX_FEATURE_POWER_SAVE
+private:
+	IHXPowerSave* m_pPowerSave;
+	IHXScheduler3* m_pScheduler3;
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 };
 
 #endif _HX_MMF_STATE_CTRL_H_

------------------------------------------------------------------------------------------------------------

Index: hxmmfstatectrl.cpp
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/hxmmfstatectrl.cpp,v
retrieving revision 1.32.12.13
diff -u -r1.32.12.13 hxmmfstatectrl.cpp
--- hxmmfstatectrl.cpp	12 Jul 2010 16:43:48 -0000	1.32.12.13
+++ hxmmfstatectrl.cpp	31 Aug 2010 18:56:21 -0000
@@ -307,7 +307,16 @@
 ULONG32
 HXMMFStateCtrl::GetPosition()
 {
-    return(m_posLength);
+#ifdef HELIX_FEATURE_POWER_SAVE
+	if(m_pScheduler3
+	&& m_pScheduler3->IsPaused()
+	&& m_pPlayerControl
+	&& m_pPlayerControl->m_pHXPlayer)
+	{
+		m_posLength = m_pPlayerControl->m_pHXPlayer->GetCurrentPlayTime();
+	}
+#endif /*HELIX_FEATURE_POWER_SAVE*/
+	return m_posLength;
 }
 
 ULONG32
@@ -417,6 +426,10 @@
         HX_RELEASE(m_pSiteSupplier);
         HX_RELEASE(m_pClientEngine);
 
+#ifdef HELIX_FEATURE_POWER_SAVE
+        HX_RELEASE(m_pPowerSave);
+        HX_RELEASE(m_pScheduler3);
+#endif /*HELIX_FEATURE_POWER_SAVE*/
         if(m_pPlayerControl != NULL)
         {
             if (m_pPlayerControl->m_pHXPlayer)
@@ -452,6 +465,10 @@
     , m_clientTid(0)
     , m_bPlayPending(FALSE)
     , m_bSurfaceCreated(FALSE)
+#ifdef HELIX_FEATURE_POWER_SAVE
+    ,m_pPowerSave(NULL)
+    ,m_pScheduler3(NULL)
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 {
     m_pSiteSupplier = NULL;
     m_pPrefs = NULL;
@@ -527,6 +544,13 @@
     {
         User::Leave(KErrNoMemory);
     }
+#ifdef HELIX_FEATURE_POWER_SAVE
+	//no need to  check the memory allocation here. It is done above.
+    m_pClientEngine->QueryInterface(IID_IHXPowerSave, (void**)&m_pPowerSave);
+
+    HX_RELEASE(m_pScheduler3);
+    QueryInterface(IID_IHXScheduler3, (void**)&m_pScheduler3);
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 
     InitAdviseSinks();
     SetupAPSelectorL();
@@ -1049,6 +1073,33 @@
 	return m_clientTid;
 }
 
+void HXMMFStateCtrl::StartPowerSave()
+{
+    HX_RESULT retVal = HXR_FAIL;
+
+
+#ifdef HELIX_FEATURE_POWER_SAVE
+    HXLOGL2( HXLOG_SMMF, "HXMMFStateCtrl::StartPowerSave  m_pPowerSave:%p", m_pPowerSave);
+    if(m_pPowerSave)
+    {
+        retVal = m_pPowerSave->StartPowerSave();
+    }
+#endif
+
+}
+
+
+void HXMMFStateCtrl::EndPowerSave()
+{
+#ifdef HELIX_FEATURE_POWER_SAVE
+    HXLOGL2( HXLOG_SMMF, "HXMMFStateCtrl::EndPowerSave  m_pPowerSave:%p", m_pPowerSave); 
+    if(m_pPowerSave)
+    {
+        m_pPowerSave->EndPowerSave();
+    }
+#endif
+
+}
 //Ensure timer is active.
 void HXMMFStateCtrl::SetOnPostSeekTimer()
 {  


---------------------------------------------------------------------------------------------------------

Index: hxmmfaudioctrl.h
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/audiocontroller/hxmmfaudioctrl.h,v
retrieving revision 1.9.32.5
diff -u -r1.9.32.5 hxmmfaudioctrl.h
--- hxmmfaudioctrl.h	4 May 2010 00:23:39 -0000	1.9.32.5
+++ hxmmfaudioctrl.h	31 Aug 2010 18:58:24 -0000
@@ -100,6 +100,7 @@
         virtual void PauseL();
         virtual void StopL();
         virtual void PrimeL();
+        virtual void SetPositionL(const TTimeIntervalMicroSeconds& aPosition);
 
         //
         //   MMMFAudioPlayControllerCustomCommandImplementor Methods


----------------------------------------------------------------------------------------------------------

Index: hxmmfaudioctrl.cpp
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/audiocontroller/hxmmfaudioctrl.cpp,v
retrieving revision 1.32.4.10
diff -u -r1.32.4.10 hxmmfaudioctrl.cpp
--- hxmmfaudioctrl.cpp	1 Jun 2010 04:04:20 -0000	1.32.4.10
+++ hxmmfaudioctrl.cpp	31 Aug 2010 19:00:42 -0000
@@ -258,6 +258,7 @@
         
         ResumeScheduler();
 
+        m_pStateCtrl->StartPowerSave();
 		
         if(m_uStartWindowPosition == TTimeIntervalMicroSeconds(0) &&
             m_uEndWindowPosition == DurationL())
@@ -976,7 +977,12 @@
 		}
         User::Leave(lError);
     }
-
+    // Pause the scheduler
+    if(m_bLocalPlayback)
+    {
+        HXLOGL1( HXLOG_SMMF, "CHXAudioController::AddDataSourceL() Pausing Scheduler");
+        PauseScheduler();
+    }
 }
 
 
@@ -1106,5 +1112,18 @@
 {
     return KErrNotSupported;
 }
+void
+CHXAudioController::SetPositionL( const TTimeIntervalMicroSeconds& aPosition )
+{	
+    HXLOGL1(HXLOG_SMMF, "CHXAudioController::SetPositionL() ");
+	
+    if(m_pStateCtrl != NULL)
+    {
+        m_pStateCtrl->EndPowerSave();
+	
+        HXMMFBaseCtrl::SetPositionL ( aPosition );
+    }
+
+}
     
 // End of File

---------------------------------------------------------------------------------------------------------

Index: hxmmfctrlimpl.cpp
===================================================================
RCS file: /cvsroot/clientapps/symbianMmf/videocontroller/hxmmfctrlimpl.cpp,v
retrieving revision 1.91.4.12
diff -u -r1.91.4.12 hxmmfctrlimpl.cpp
--- hxmmfctrlimpl.cpp	12 Jul 2010 16:43:47 -0000	1.91.4.12
+++ hxmmfctrlimpl.cpp	31 Aug 2010 19:04:24 -0000
@@ -1331,7 +1331,7 @@
     HXLOGL1(HXLOG_SMMF, "HXMMFCtrlImpl::OnPresentationClosed(m_closePlayer[%d])",m_closePlayer);
 
     TInt isLive = 0;
-
+    HXBOOL bPauseSched = FALSE;
 
     // seek the datasource to initial position.
     if (m_pDataSource)
@@ -1353,24 +1353,36 @@
         {
             SendEvent( m_nextEvent, m_ulLastError );
 
-            if(m_bLocalPlayback && m_ulLastError == HXR_OK)
-            {
-                PauseScheduler();
-            }
+            bPauseSched = TRUE;
 
         }
         m_nextEvent = ErrorEvent;
 
     }
-    else if (m_pMetaData)
+    else
+    {
+        if (m_pMetaData)
     {
         m_pMetaData->FindMetaDataValueByName("LiveStream",isLive);
 
         if (m_nextEvent == ErrorEvent && isLive)
         {
             SendEvent( ErrorEvent, HXR_CLOSED );
+            } 
+            else if(!isLive) 
+            {
+                bPauseSched = TRUE;
+            }
+        }
+        else
+        {
+            bPauseSched = TRUE;
         }
     }
+    if(m_bLocalPlayback && m_ulLastError == HXR_OK && bPauseSched)
+    {
+        PauseScheduler();
+    }
 }
 
---------------------------------------------------------------------------------------------------------------


Index: hxcore.h
===================================================================
RCS file: /cvsroot/common/include/hxcore.h,v
retrieving revision 1.24.2.1
diff -u -r1.24.2.1 hxcore.h
--- hxcore.h	18 Sep 2009 04:48:22 -0000	1.24.2.1
+++ hxcore.h	26 Aug 2010 15:31:58 -0000
@@ -2412,81 +2412,6 @@
  *
  */
 
-DEFINE_GUID(IID_IHXPowerSave, 0xf52067d2, 0xbf0b, 0x4081, 0xb3, 0x6f, 0xca, 0xee, 0x79, 0x24, 0x21, 0x9a);
-
-#undef  INTERFACE
-#define INTERFACE   IHXPowerSave
-
-DECLARE_INTERFACE_(IHXPowerSave, IUnknown)
-{
-     /*
-      * IUnknown methods
-      */
-     STDMETHOD(QueryInterface)		(THIS_
-					 REFIID riid,
-					 void** ppvObj) PURE;
-
-     STDMETHOD_(ULONG32,AddRef)		(THIS) PURE;
-
-     STDMETHOD_(ULONG32,Release)	(THIS) PURE;
-
-     /*
-      * IHXPowerSave methods
-      */
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::StartPowerSave
-      * Purpose:
-      *     same as EventOccurred with HX_POWERSAVE_ON
-      */
-     STDMETHOD(StartPowerSave)			(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::EndPowerSave
-      * Purpose:
-      *     same as EventOccurred with HX_POWERSAVE_OFF
-      */
-     STDMETHOD(EndPowerSave)			(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::IsInPowerSave
-      * Purpose:
-      *	    Check whether it is in power save mode. 
-      *     TRUE if operation on power save mode, FALSE otherwise
-      */
-     STDMETHOD_(HXBOOL,IsInPowerSave)		(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::CanStartPowerSave
-      * Purpose:
-      *     Check whether power-save-mode can be turned on.
-      *     TRUE if power save mode can be turned on at the time of the call.
-      */
-     STDMETHOD_(HXBOOL,CanStartPowerSave)	(THIS) PURE;
-
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::GetWakeUpInterval
-      * Purpose:
-      *     Get time interval engine will nomally wake up in to operate
-      */
-     STDMETHOD_(ULONG32,GetWakeUpInterval)	(THIS) PURE;
-     /************************************************************************
-      * Method:
-      *     IHXPowerSave::SetWakeUpInterval
-      * Purpose:
-      *     Set time interval engine will nomally wake up in to operate  (use 
-      *     this only to override default)
-      */
-     STDMETHOD_(ULONG32,SetWakeUpInterval)	(THIS_ 
-						 ULONG32 /*IN*/ ulWakeUpInterval) PURE;
-
-};
-
 #include "hxcomptr.h"
 DEFINE_SMART_PTR(IHXStream)
 DEFINE_SMART_PTR(IHXStream2)
@@ -2517,9 +2442,6 @@
 DEFINE_SMART_PTR(IHXPlayerPresentation)
 DEFINE_SMART_PTR(IHXCoreMutex)
 DEFINE_SMART_PTR(IHXMacBlitMutex)
-#if defined(HELIX_FEATURE_POWER_SAVE)
-  DEFINE_SMART_PTR(IHXPowerSave)
-#endif /* defined(HELIX_FEATURE_POWER_SAVE) */
 
 #if defined _UNIX && !defined (_VXWORKS)
 DEFINE_SMART_PTR(IHXClientEngineSelector)

-------------------------------------------------------------------------------------------------------------------

Index: hxiids.h
===================================================================
RCS file: /cvsroot/common/include/hxiids.h,v
retrieving revision 1.168.4.4
diff -u -r1.168.4.4 hxiids.h
--- hxiids.h	7 Jul 2010 23:19:56 -0000	1.168.4.4
+++ hxiids.h	9 Aug 2010 16:29:30 -0000
@@ -425,6 +425,8 @@
 DEFINE_GUID_ENUM(IID_IHXPersistentComponent,    0x00000416, 0x901, 0x11d1, 0x8b, 0x6, 0x0, 0xa0, 0x24, 0x40, 0x6d, 0x59)
 DEFINE_GUID_ENUM(IID_IHXExternalSystemClock,            0x6de011a7, 0xef05, 0x417b, 0x93, 0x67, 0x6f, 0xe0, 0xe4, 0x44, 0x4, 0xd5)
 DEFINE_GUID_ENUM(IID_IHXPowerSave,                      0xf52067d2, 0xbf0b, 0x4081, 0xb3, 0x6f, 0xca, 0xee, 0x79, 0x24, 0x21, 0x9a)
+DEFINE_GUID_ENUM(IID_IHXTimeLineLimit, 
+				0xb91a83e0, 0xef48, 0x11de, 0xaa, 0xca, 0x0, 0x2, 0xa5, 0xd5, 0xc5, 0x1b)
 // $Private:
 DEFINE_GUID_ENUM(IID_IHXSourceBufferingStats,       0x00000418, 0x901, 0x11d1, 0x8b, 0x6, 0x0, 0xa0, 0x24, 0x40, 0x6d, 0x59)
 DEFINE_GUID_ENUM(IID_IHXSourceBufferingStats2,       0x00000418, 0x901, 0x11d1, 0x8b, 0x6, 0x0, 0xa0, 0x24, 0x40, 0x6d, 0x5a)

--------------------------------------------------------------------------------------------------------------------

Index: hxengin.h
===================================================================
RCS file: /cvsroot/common/include/hxengin.h,v
retrieving revision 1.40
diff -u -r1.40 hxengin.h
--- hxengin.h	5 May 2009 16:26:33 -0000	1.40
+++ hxengin.h	9 Aug 2010 16:29:09 -0000
@@ -311,6 +311,8 @@
     STDMETHOD_(HXBOOL, AreImmediatesPending)(THIS) PURE;
 };
 
+#undef  INTERFACE
+#define INTERFACE   IHXScheduler3
 DECLARE_INTERFACE_(IHXScheduler3, IUnknown)
 {
     /*

--------------------------------------------------------------------------------------------------------------------
Index: helix-client-symbian-4-common.pfi
===================================================================
RCS file: /cvsroot/ribosome/build/umakepf/helix-client-symbian-4-common.pfi,v
retrieving revision 1.5
diff -u -r1.5 helix-client-symbian-4-common.pfi
--- helix-client-symbian-4-common.pfi	12 May 2010 19:25:47 -0000	1.5
+++ helix-client-symbian-4-common.pfi	7 Sep 2010 19:20:22 -0000
@@ -67,3 +67,6 @@
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_S60_AVKON')
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_VIDEOCTRL_PKG')
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_PHONON_PKG')
+
+project.AddDefines('HELIX_FEATURE_POWER_SAVE')
+

--------------------------------------------------------------------------------------------------------------------

Index: helix-client-symbian-4-integration-common.pfi
===================================================================
RCS file: /cvsroot/ribosome/build/umakepf/helix-client-symbian-4-integration-common.pfi,v
retrieving revision 1.6
diff -u -r1.6 helix-client-symbian-4-integration-common.pfi
--- helix-client-symbian-4-integration-common.pfi	12 May 2010 19:48:50 -0000	1.6
+++ helix-client-symbian-4-integration-common.pfi	7 Sep 2010 19:20:38 -0000
@@ -75,3 +75,5 @@
 project.RemoveDefines('HELIX_FEATURE_MMF_CUSTOM_COMMAND')
 project.RemoveDefines('HELIX_FEATURE_MMF_STREAM_CONTROL')
 project.RemoveDefines('HELIX_FEATURE_SYMBIAN_VIDEOCTRL_PKG')
+
+project.AddDefines('HELIX_FEATURE_POWER_SAVE')


 
 

-------------- next part --------------
#ifndef _HXPOWERSAVE_H_
#define _HXPOWERSAVE_H_




typedef _INTERFACE IHXPowerSave IHXPowerSave;

/****************************************************************************
*
*  Interface:
*
*	IHXPowerSave
*
*  Purpose:
*
*	Interface for IHXPowerSave objects.
*
*  IID_IHXPowerSave:
*
*   {F52067D2-BF0B-4081-B36F-CAEE7924219A}
*
*/

#undef INTERFACE
#define INTERFACE IHXPowerSave
DEFINE_GUID(IID_IHXPowerSave, 0xf52067d2, 0xbf0b, 0x4081, 0xb3, 0x6f, 0xca, 0xee, 0x79, 0x24, 0x21, 0x9a);

DECLARE_INTERFACE_(IHXPowerSave, IUnknown)
{

    /* IUnknown methods. */
    STDMETHOD(QueryInterface)   (THIS_ REFIID riid, void** ppvObj) PURE;
    STDMETHOD_(ULONG32,AddRef)  (THIS) PURE;
    STDMETHOD_(ULONG32,Release) (THIS) PURE;

	STDMETHOD(StartPowerSave) (THIS) PURE;
	STDMETHOD(EndPowerSave ) (THIS) PURE;
	STDMETHOD_(HXBOOL,IsInPowerSave) (THIS) PURE;
	STDMETHOD_(HXBOOL,CanStartPowerSave) (THIS) PURE;
	STDMETHOD_(ULONG32,GetWakeUpInterval ) (THIS) PURE;
	STDMETHOD(SetWakeUpInterval  ) (THIS_ ULONG32 ulWakeUpInterval ) PURE;
};


#endif /*_HXPOWERSAVE_H_*/
-------------- next part --------------
#ifndef _HXTIMELINELIMIT_H_
#define _HXTIMELINELIMIT_H_



typedef _INTERFACE IHXTimeLineLimit IHXTimeLineLimit;

/****************************************************************************
*
*  Interface:
*
*	IHXTimeLineLimit
*
*  Purpose:
*
*	Interface for IHXTimeLineLimit objects.
*
*  IID_IHXTimeLineLimit:
*
*	{b91a83e0-ef48-11de-aaca-0002a5d5c51b)
*
*/

#undef INTERFACE
#define INTERFACE IHXTimeLineLimit

DEFINE_GUID(IID_IHXTimeLineLimit, 0xb91a83e0, 0xef48, 0x11de, 0xaa, 0xca, 0x0, 0x2, 0xa5, 0xd5, 0xc5, 0x1b);

DECLARE_INTERFACE_(IHXTimeLineLimit, IUnknown)
{
	/* IUnknown methods. */
    STDMETHOD(QueryInterface)   (THIS_ REFIID riid, void** ppvObj) PURE;
    STDMETHOD_(ULONG32,AddRef)  (THIS) PURE;
    STDMETHOD_(ULONG32,Release) (THIS) PURE;
	
	STDMETHOD(SetLimit) (THIS_ UINT32 ulLimitInMs )PURE;
	STDMETHOD(GetLimit) (THIS_ REF(UINT32) ulLimitInMs )PURE;
	STDMETHOD(ResetLimit) (THIS) PURE;
};

#endif /*_HXTIMELINELIMIT_H_*/
-------------- next part --------------
_______________________________________________
Clientapps-dev mailing list
Clientapps-dev@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/clientapps-dev
-------------- next part --------------
_______________________________________________
Clientapps-dev mailing list
Clientapps-dev@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/clientapps-dev
From tseaward at real.com  Mon Sep 13 12:00:22 2010
From: tseaward at real.com (Tony Seaward)
Date: Mon Sep 13 18:23:31 2010
Subject: [Helix-client-dev] Re: RESEND: [datatype-dev] [Client-dev]
 [Clientapps-dev]	[Nokia-private-dev]CR:
 Symbian	Add Power Save Support to Brizo420 and	head
In-Reply-To: 
References: 
Message-ID: <4C8E82D6.8020404@real.com>

We'll get this reviewed today. Sorry for the delay.

Tony Seaward
Program Manager
RealNetworks 


On 9/13/10 9:06 AM, xiaolin.lliu@nokia.com wrote:
>  
>
> ------------------------------------------------------------------------
> *From:* clientapps-dev-bounces@helixcommunity.org
> [mailto:clientapps-dev-bounces@helixcommunity.org] *On Behalf Of *Lliu
> Xiaolin (Nokia-MS/Dallas)
> *Sent:* Friday, September 10, 2010 1:31 PM
> *To:* datatype-dev@helixcommunity.org;
> clientapps-dev@helixcommunity.org; helix-client-dev@helixcommunity.org
> *Subject:* RESEND: [datatype-dev] [Client-dev] [Clientapps-dev] CR:
> Symbian Add Power Save Support to Brizo420 and head
>
>  
>
> ------------------------------------------------------------------------
> *From:* clientapps-dev-bounces@helixcommunity.org
> [mailto:clientapps-dev-bounces@helixcommunity.org] *On Behalf Of *Lliu
> Xiaolin (Nokia-MS/Dallas)
> *Sent:* Tuesday, September 07, 2010 2:54 PM
> *To:* datatype-dev@helixcommunity.org;
> clientapps-dev@helixcommunity.org; helix-client-dev@helixcommunity.org
> *Subject:* [datatype-dev] [Client-dev] [Clientapps-dev] CR: Symbian
> Add Power Save Support to Brizo420 and head
>
>  
> "Nokia submits this code under the terms of a commercial contribution
> agreement with Real Networks, and I am authorized to contribute this
> code under said agreement."
>  
>  
> Modified by:  xiaolin.lliu@nokia.com
>  
> Reviewed by:
>  
> Date: 08/31/2010
>  
> Project: symbian_client_apps
>  
> Synopsis: Power Save
>  
> Overview: Reduce the power consumption for music playback
>  
> Solution: Helix goes to the power save mode when the following
> conditions are met:
> -One source is available
> -local audio playback
> -Power save feature is enabled
> Symbian audio device controls the scheduler during the power save
> mode. Audio device makes the decision when the scheduler should be
> paused or resumed. PowerSave feature is implemented to allow the
> playback engine to be in sleep between high water mark and low water mark.
>  
>  
> Files Added:
> \common\include\hxTimelineLimit.h
> \common\include\hxPowerSave.h
>  
>  
> Files Modified:
>  
> \datatype\mdf\audio\dsp\mdfauddevice.h 
> \datatype\mdf\audio\dsp\mdfauddevice.cpp 
> \datatype\mdf\audio\dsp\mdfdevsound.h 
> \datatype\mdf\audio\dsp\mdfdevsound.cpp 
>  
> \client\audiosvc\pub\hxaudply.h 
> \client\audiosvc\hxaudply.cpp
> \client\audiosvc\pub\hxaudsec.h
> \client\audiosvc\hxaudsec.cpp
>  
> \client\core\pub\hxcleng.h 
> \client\core\pub\hxcleng.cpp
> \client\core\pub\hxplay.h
> \client\core\hxplay.cpp 
> \client\medpltfm\pub\chxmedpltfmsched.h 
> \client\medpltfm\chxmedpltfmsched.cpp 
> \client\medpltfm\chxmedpltfm.cpp
>  
> \clientapps\symbiancommon\config\R1_Mobile_4_0_Factory.cfg
> \clientapps\symbianMmf\hxmmfstatectrl.h
> \clientapps\symbianMmf\hxmmfstatectrl.cpp 
> \clientapps\symbianMmf\audiocontroller\hxmmfaudioctrl.h 
> \clientapps\symbianMmf\audiocontroller\hxmmfaudioctrl.cpp 
> \clientapps\symbianMmf\videocontroller\hxmmfctrlimpl.cpp 
>  
> \common\include\hxcore.h 
> \common\include\hxiids.h 
> \common\include\hxengin.h
>  
> \ribosome\build\umakepf\helix-client-symbian-4-integration-common.pfi
> \ribosome\build\umakepf\helix-client-symbian-4-common.pfi
>  
>  
> Image Size and Heap Use impact: minor
>  
> Module Release testing :
>  
> Test case(s) Added  : 
>  
> Memory leak : No
>  
> Platforms and Profiles Build Verified:
> helix-client-s60-52-mmf-mdf-dsp
>  
> Platforms and Profiles Functionality verified: armv5
>  
> Branch: 420Brizo, HEAD.
>  
>  
>  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.helixcommunity.org/pipermail/helix-client-dev/attachments/20100913/b1c21025/attachment.html
From sfu at real.com  Mon Sep 13 12:52:00 2010
From: sfu at real.com (Sheldon Fu)
Date: Mon Sep 13 19:15:38 2010
Subject: [Helix-client-dev] Re: RESEND: [datatype-dev] [Client-dev]
 [Clientapps-dev]	[Nokia-private-dev]CR:
 Symbian	Add Power Save Support to Brizo420 and	head
In-Reply-To: 
References: 
Message-ID: <4C8E8EF0.4030203@real.com>

This looks fine.

Moving IHXPowerSave definition into a separate header probably breaks 
the Intel Morrestown DSP decoding work we've done but since that project 
is idle, we can fix it later.

fxd

xiaolin.lliu@nokia.com wrote:
>  
>
> *From:* clientapps-dev-bounces@helixcommunity.org 
> [mailto:clientapps-dev-bounces@helixcommunity.org] *On Behalf Of *Lliu 
> Xiaolin (Nokia-MS/Dallas)
> *Sent:* Friday, September 10, 2010 1:31 PM
> *To:* datatype-dev@helixcommunity.org; 
> clientapps-dev@helixcommunity.org; helix-client-dev@helixcommunity.org
> *Subject:* RESEND: [datatype-dev] [Client-dev] [Clientapps-dev] CR: 
> Symbian Add Power Save Support to Brizo420 and head
>
>  
>
> *From:* clientapps-dev-bounces@helixcommunity.org 
> [mailto:clientapps-dev-bounces@helixcommunity.org] *On Behalf Of *Lliu 
> Xiaolin (Nokia-MS/Dallas)
> *Sent:* Tuesday, September 07, 2010 2:54 PM
> *To:* datatype-dev@helixcommunity.org; 
> clientapps-dev@helixcommunity.org; helix-client-dev@helixcommunity.org
> *Subject:* [datatype-dev] [Client-dev] [Clientapps-dev] CR: Symbian 
> Add Power Save Support to Brizo420 and head
>
>  
> "Nokia submits this code under the terms of a commercial contribution 
> agreement with Real Networks, and I am authorized to contribute this 
> code under said agreement."
>  
>  
> Modified by:  xiaolin.lliu@nokia.com
>  
> Reviewed by:
>  
> Date: 08/31/2010
>  
> Project: symbian_client_apps
>  
> Synopsis: Power Save
>  
> Overview: Reduce the power consumption for music playback
>  
> Solution: Helix goes to the power save mode when the following 
> conditions are met:
> -One source is available
> -local audio playback
> -Power save feature is enabled
> Symbian audio device controls the scheduler during the power save 
> mode. Audio device makes the decision when the scheduler should be 
> paused or resumed. PowerSave feature is implemented to allow the 
> playback engine to be in sleep between high water mark and low water 
> mark.
>  
>  
> Files Added:
> \common\include\hxTimelineLimit.h
> \common\include\hxPowerSave.h
>  
>  
> Files Modified:
>  
> \datatype\mdf\audio\dsp\mdfauddevice.h 
> \datatype\mdf\audio\dsp\mdfauddevice.cpp 
> \datatype\mdf\audio\dsp\mdfdevsound.h 
> \datatype\mdf\audio\dsp\mdfdevsound.cpp 
>  
> \client\audiosvc\pub\hxaudply.h 
> \client\audiosvc\hxaudply.cpp
> \client\audiosvc\pub\hxaudsec.h
> \client\audiosvc\hxaudsec.cpp
>  
> \client\core\pub\hxcleng.h 
> \client\core\pub\hxcleng.cpp
> \client\core\pub\hxplay.h
> \client\core\hxplay.cpp 
> \client\medpltfm\pub\chxmedpltfmsched.h 
> \client\medpltfm\chxmedpltfmsched.cpp 
> \client\medpltfm\chxmedpltfm.cpp
>  
> \clientapps\symbiancommon\config\R1_Mobile_4_0_Factory.cfg
> \clientapps\symbianMmf\hxmmfstatectrl.h
> \clientapps\symbianMmf\hxmmfstatectrl.cpp 
> \clientapps\symbianMmf\audiocontroller\hxmmfaudioctrl.h 
> \clientapps\symbianMmf\audiocontroller\hxmmfaudioctrl.cpp 
> \clientapps\symbianMmf\videocontroller\hxmmfctrlimpl.cpp 
>  
> \common\include\hxcore.h 
> \common\include\hxiids.h 
> \common\include\hxengin.h
>  
> \ribosome\build\umakepf\helix-client-symbian-4-integration-common.pfi
> \ribosome\build\umakepf\helix-client-symbian-4-common.pfi
>  
>  
> Image Size and Heap Use impact: minor
>  
> Module Release testing :
>  
> Test case(s) Added  : 
>  
> Memory leak : No
>  
> Platforms and Profiles Build Verified:
> helix-client-s60-52-mmf-mdf-dsp
>  
> Platforms and Profiles Functionality verified: armv5
>  
> Branch: 420Brizo, HEAD.
>  
>  
>  


From xiaolin.lliu at nokia.com  Wed Sep 15 11:33:12 2010
From: xiaolin.lliu at nokia.com (xiaolin.lliu@nokia.com)
Date: Wed Sep 15 17:57:22 2010
Subject: [Helix-client-dev] CN: [datatype-dev] [Client-dev] [Clientapps-dev]
	[Nokia-private-dev]CR: Symbian	Add Power Save
	Support to Brizo420 and	head
In-Reply-To: <4C8E8EF0.4030203@real.com>
References: 
	<4C8E8EF0.4030203@real.com>
Message-ID: 


 Checked in to brizo 420 and head

-----Original Message-----
From: ext Sheldon Fu [mailto:sfu@real.com] 
Sent: Monday, September 13, 2010 3:52 PM
To: Lliu Xiaolin (Nokia-MS/Dallas)
Cc: datatype-dev@helixcommunity.org; clientapps-dev@helixcommunity.org; helix-client-dev@helixcommunity.org; nokia-private-dev@helixcommunity.org
Subject: Re: RESEND: [datatype-dev] [Client-dev] [Clientapps-dev] [Nokia-private-dev]CR: Symbian Add Power Save Support to Brizo420 and head

This looks fine.

Moving IHXPowerSave definition into a separate header probably breaks the Intel Morrestown DSP decoding work we've done but since that project is idle, we can fix it later.

fxd

xiaolin.lliu@nokia.com wrote:
>  
>
> *From:* clientapps-dev-bounces@helixcommunity.org
> [mailto:clientapps-dev-bounces@helixcommunity.org] *On Behalf Of *Lliu 
> Xiaolin (Nokia-MS/Dallas)
> *Sent:* Friday, September 10, 2010 1:31 PM
> *To:* datatype-dev@helixcommunity.org; 
> clientapps-dev@helixcommunity.org; helix-client-dev@helixcommunity.org
> *Subject:* RESEND: [datatype-dev] [Client-dev] [Clientapps-dev] CR: 
> Symbian Add Power Save Support to Brizo420 and head
>
>  
>
> *From:* clientapps-dev-bounces@helixcommunity.org
> [mailto:clientapps-dev-bounces@helixcommunity.org] *On Behalf Of *Lliu 
> Xiaolin (Nokia-MS/Dallas)
> *Sent:* Tuesday, September 07, 2010 2:54 PM
> *To:* datatype-dev@helixcommunity.org; 
> clientapps-dev@helixcommunity.org; helix-client-dev@helixcommunity.org
> *Subject:* [datatype-dev] [Client-dev] [Clientapps-dev] CR: Symbian 
> Add Power Save Support to Brizo420 and head
>
>  
> "Nokia submits this code under the terms of a commercial contribution 
> agreement with Real Networks, and I am authorized to contribute this 
> code under said agreement."
>  
>  
> Modified by:  xiaolin.lliu@nokia.com
>  
> Reviewed by:
>  
> Date: 08/31/2010
>  
> Project: symbian_client_apps
>  
> Synopsis: Power Save
>  
> Overview: Reduce the power consumption for music playback
>  
> Solution: Helix goes to the power save mode when the following 
> conditions are met:
> -One source is available
> -local audio playback
> -Power save feature is enabled
> Symbian audio device controls the scheduler during the power save 
> mode. Audio device makes the decision when the scheduler should be 
> paused or resumed. PowerSave feature is implemented to allow the 
> playback engine to be in sleep between high water mark and low water 
> mark.
>  
>  
> Files Added:
> \common\include\hxTimelineLimit.h
> \common\include\hxPowerSave.h
>  
>  
> Files Modified:
>  
> \datatype\mdf\audio\dsp\mdfauddevice.h
> \datatype\mdf\audio\dsp\mdfauddevice.cpp
> \datatype\mdf\audio\dsp\mdfdevsound.h
> \datatype\mdf\audio\dsp\mdfdevsound.cpp
>  
> \client\audiosvc\pub\hxaudply.h
> \client\audiosvc\hxaudply.cpp
> \client\audiosvc\pub\hxaudsec.h
> \client\audiosvc\hxaudsec.cpp
>  
> \client\core\pub\hxcleng.h
> \client\core\pub\hxcleng.cpp
> \client\core\pub\hxplay.h
> \client\core\hxplay.cpp
> \client\medpltfm\pub\chxmedpltfmsched.h
> \client\medpltfm\chxmedpltfmsched.cpp
> \client\medpltfm\chxmedpltfm.cpp
>  
> \clientapps\symbiancommon\config\R1_Mobile_4_0_Factory.cfg
> \clientapps\symbianMmf\hxmmfstatectrl.h
> \clientapps\symbianMmf\hxmmfstatectrl.cpp
> \clientapps\symbianMmf\audiocontroller\hxmmfaudioctrl.h
> \clientapps\symbianMmf\audiocontroller\hxmmfaudioctrl.cpp
> \clientapps\symbianMmf\videocontroller\hxmmfctrlimpl.cpp
>  
> \common\include\hxcore.h
> \common\include\hxiids.h
> \common\include\hxengin.h
>  
> \ribosome\build\umakepf\helix-client-symbian-4-integration-common.pfi
> \ribosome\build\umakepf\helix-client-symbian-4-common.pfi
>  
>  
> Image Size and Heap Use impact: minor
>  
> Module Release testing :
>  
> Test case(s) Added  : 
>  
> Memory leak : No
>  
> Platforms and Profiles Build Verified:
> helix-client-s60-52-mmf-mdf-dsp
>  
> Platforms and Profiles Functionality verified: armv5
>  
> Branch: 420Brizo, HEAD.
>  
>  
>  


From sreesudhanr at real.com  Thu Sep 16 14:23:07 2010
From: sreesudhanr at real.com (Sreesudhan Ramakrish Ramkumar)
Date: Thu Sep 16 20:45:52 2010
Subject: [Helix-client-dev] Error while generating patch for Helix DNA client
Message-ID: <766B5A29D28DA442AB229AAEE2AFC4450804F33376@SEAMBX.corp.real.com>

Hi,

I need to generate patch for my new code changes in helix DNA client. I executed 'cvs diff -uw' in cygwin, I am getting following error.

$ cvs diff -uw
/CVSROOTccess /cvsroot/protocol
No such file or directory

Can you please help me resolve this error ?

Thank you,
Sreesudhan.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.helixcommunity.org/pipermail/helix-client-dev/attachments/20100916/ed6600d0/attachment-0001.html
From kliu at real.com  Thu Sep 16 23:18:52 2010
From: kliu at real.com (Kinson Liu)
Date: Fri Sep 17 05:41:14 2010
Subject: [Helix-client-dev] RE: Error while generating patch for Helix DNA
	client
In-Reply-To: <766B5A29D28DA442AB229AAEE2AFC4450804F33376@SEAMBX.corp.real.com>
References: <766B5A29D28DA442AB229AAEE2AFC4450804F33376@SEAMBX.corp.real.com>
Message-ID: 

Please make sure the CVS folder inside is not damaged.

Kinson

________________________________
From: helix-client-dev-bounces@helixcommunity.org [mailto:helix-client-dev-bounces@helixcommunity.org] On Behalf Of Sreesudhan Ramakrish Ramkumar
Sent: Friday, September 17, 2010 6:23 AM
To: helix-client-dev@helixcommunity.org
Subject: [Helix-client-dev] Error while generating patch for Helix DNA client

Hi,

I need to generate patch for my new code changes in helix DNA client. I executed 'cvs diff -uw' in cygwin, I am getting following error.

$ cvs diff -uw
/CVSROOTccess /cvsroot/protocol
No such file or directory

Can you please help me resolve this error ?

Thank you,
Sreesudhan.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.helixcommunity.org/pipermail/helix-client-dev/attachments/20100917/75c7b7ed/attachment.html
From rhuang at real.com  Thu Sep 23 13:53:28 2010
From: rhuang at real.com (Renjie Huang)
Date: Thu Sep 23 20:14:35 2010
Subject: [Helix-client-dev] Fail to play H263+ video of custom format 
Message-ID: <766B5A29D28DA442AB229AAEE2AFC44508043BEB26@SEAMBX.corp.real.com>

Hi

I have a question regarding to H263+ video playback.  Helix always crashes when playing  H263+ video of custom format (e.g. 800*480, 720*576). The reason is that iSliceMBA ( in datatype-restricted/rm/video/codec/g2mp4combo/dec/d3mvdec.cpp) read from the slice header is wrong. For example, the  iSliceMBA got by CH263pBs::GetSliceHeader() ( in datatype-restricted/rm/video/codec/g2mp4combo/common/c3bsx.cpp) from a 800*480 H263+ clip is 1550, while the total micro blocks (m_iTotalNumberOfMBs) is only 50*30 = 1500.  From the logic of the code, the way of reading the slicing header seems correct.  Not understanding why the value is wrong.The clips can be played with other media players. Can someone give me some help on that? Thanks.
From xiaolin.lliu at nokia.com  Fri Sep 24 07:02:30 2010
From: xiaolin.lliu at nokia.com (xiaolin.lliu@nokia.com)
Date: Fri Sep 24 13:23:21 2010
Subject: [Helix-client-dev] RESEND: [client-dev] CR Symbian: Fix coverity
 check finding in hxaudsec.cpp
Message-ID: 




Modified by:  xiaolin.lliu@nokia.com

Reviewed by:

Date: 09/20/2010

Project: symbian_client_apps

Synopsis: Using pointer after NULL check

Overview: Coverity check complains that a pointer is used before NULL check.


Files Added:

Files Modified:

\client\audiosvc\hxaudsec.cpp



Image Size and Heap Use impact: minor

Module Release testing :

Test case(s) Added  :

Memory leak : No

Platforms and Profiles Build Verified:
helix-client-s60-52-mmf-mdf-dsp

Platforms and Profiles Functionality verified: armv5

Branch: 420Brizo, HEAD.


Index: hxaudses.cpp
===================================================================
RCS file: /cvsroot/client/audiosvc/hxaudses.cpp,v
retrieving revision 1.84.2.1.2.2
diff -u -r1.84.2.1.2.2 hxaudses.cpp
--- hxaudses.cpp        14 Sep 2010 18:13:37 -0000      1.84.2.1.2.2
+++ hxaudses.cpp        20 Sep 2010 21:21:02 -0000
@@ -4749,10 +4749,10 @@
     {
         if (CanStartPowerSave())
         {
-            CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
-            CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
             if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
             {
+                CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+                CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
                 theErr = pPlayer->StartPowerSave();

                 if (theErr == HXR_OK)



-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.helixcommunity.org/pipermail/helix-client-dev/attachments/20100924/1bb76352/attachment.html
From jgordon at real.com  Fri Sep 24 09:03:14 2010
From: jgordon at real.com (Jamie Gordon)
Date: Fri Sep 24 15:29:24 2010
Subject: [Helix-client-dev] Re: [Nokia-private-dev] RESEND: [client-dev] CR
 Symbian: Fix coverity check finding in hxaudsec.cpp
In-Reply-To: 
References: 
Message-ID: <4C9CD9D2.1050907@real.com>

ok

On 9/24/2010 8:02 AM, xiaolin.lliu@nokia.com wrote:
> Modified by:  xiaolin.lliu@nokia.com
> Reviewed by:
> Date: 09/20/2010
> Project: symbian_client_apps
> Synopsis: Using pointer after NULL check
> Overview: Coverity check complains that a pointer is used before NULL check.
> Files Added:
> Files Modified:
> \client\audiosvc\hxaudsec.cpp
> Image Size and Heap Use impact: minor
> Module Release testing :
> Test case(s) Added :
> Memory leak : No
> Platforms and Profiles Build Verified:
> helix-client-s60-52-mmf-mdf-dsp
> Platforms and Profiles Functionality verified: armv5
> Branch: 420Brizo, HEAD.
> Index: hxaudses.cpp
> ===================================================================
> RCS file: /cvsroot/client/audiosvc/hxaudses.cpp,v
> retrieving revision 1.84.2.1.2.2
> diff -u -r1.84.2.1.2.2 hxaudses.cpp
> --- hxaudses.cpp 14 Sep 2010 18:13:37 -0000 1.84.2.1.2.2
> +++ hxaudses.cpp 20 Sep 2010 21:21:02 -0000
> @@ -4749,10 +4749,10 @@
> {
> if (CanStartPowerSave())
> {
> - CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
> - CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
> if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
> {
> + CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
> + CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
> theErr = pPlayer->StartPowerSave();
> if (theErr == HXR_OK)

From rhuang at real.com  Fri Sep 24 16:19:46 2010
From: rhuang at real.com (Renjie Huang)
Date: Fri Sep 24 22:40:21 2010
Subject: [Helix-client-dev] CR: Bug 11047 H263+ clips cause SIGABORT due to
	memory corruption
Message-ID: <766B5A29D28DA442AB229AAEE2AFC44508043BEB2F@SEAMBX.corp.real.com>

Date: 2010-09-24
Project: RealPlayer for Android Smartphones

Synopsis: H263+ clips cause SIGABORT due to memory corruption

Overview: In my test, some H263+ clips cause SIGABORT during playback. The reason is that in slice structure mode, the micro block index iMBA read from the slice header exceed the valid range and corrupt the memory.  The clips for testing are created by the SUPER video converter, which uses FFmpeg.  The comparison among Helix h263 decoder, FFmpeg h263 decoder and the ITU H263 document show that FFmpeg does not strictly follow the picture header structure format of the ITU H263 for extended type.  In FFmpeg, the SQUANT field is right after the SSS field (ituh263dec.cpp: line 1072). It also ignores the MBA value.  In ITU 263,  the fields after SSS are "ELNUM RLNUM" (page 162); the SQUANT is after fields "MBA SEPB2" (page 96). In the CR, the decoder return PIA_S_UNSUPPORTED instead of continuing when iMBA exceeds valid range. 

Reference: 
  ITU H263 doc: http://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-H.263-200501-I!!PDF-E&type=items
  FFmpeg ituh263dec.cpp: http://git.ffmpeg.org/?p=ffmpeg;a=blob;f=libavcodec/ituh263dec.c;h=8b5d9391b2e196b6767848660ecbc93497d337b8;hb=HEAD

Changed files:
datatype-restricted/rm/video/codec/g2mp4combo/dec/d3mvdec.cpp

Image Size and Heap Use impact (Client -Only):
None

Platforms and Profiles Affected:
Platform: : head, 361, and 362
Profile: helix-client-android

Distribution Libraries Affected:
NA

Distribution library impact and planned action:
NA

Platforms and Profiles Build Verified:
Platform: hxclient_3_6_1_atlas
Profile:  helix-client-android

Platforms and Profiles Functionality verified:
Platform: hxclient_3_6_1_atlas
Profile: helix-client-android


Copyright assignment: I am a RealNetworks employee or contractor
-------------- next part --------------
A non-text attachment was scrubbed...
Name: h263.diff
Type: text/x-patch
Size: 1239 bytes
Desc: h263.diff
Url : http://lists.helixcommunity.org/pipermail/helix-client-dev/attachments/20100924/042025b1/h263-0001.bin
From rhuang at real.com  Mon Sep 27 11:29:55 2010
From: rhuang at real.com (Renjie Huang)
Date: Mon Sep 27 17:50:36 2010
Subject: [Helix-client-dev] RESEND: Bug 11047 H263+ clips cause SIGABORT due
 to memory corruption
In-Reply-To: <766B5A29D28DA442AB229AAEE2AFC44508043BEB31@SEAMBX.corp.real.com>
References: <766B5A29D28DA442AB229AAEE2AFC44508043BEB31@SEAMBX.corp.real.com>
Message-ID: <766B5A29D28DA442AB229AAEE2AFC44508043BEB3C@SEAMBX.corp.real.com>

I sent to myself by mistake. Resend to  helix-client-dev@helixcommunity.org. Thanks.
________________________________________
From: Renjie Huang
Sent: Sunday, September 26, 2010 9:04 PM
To: Renjie Huang
Subject: RESEND: Bug 11047 H263+ clips cause SIGABORT due to memory corruption

I compare the source code of FFmpeg h263 encoder/decoder with Helix decoder. In the slice structure mode of H263+, the data structure format is the same. The only difference is that: FFmpeg simply ignores the first macroblock address  in the current slice. Since the testing clips can be both played with ffmpeg and gstreamer,  I think Helix should  be able to decode them correctly too. I submit a new patch to get the helix decoder to behave in the same as FFmpeg by ignoring the first macroblock address retrieved from the slice header. With that change, Helix is now able to play custom format H263+ videos.  Can someone help me review this CR? Thanks.

Changed files:
datatype-restricted/rm/video/codec/g2mp4combo/dec/d3mvdec.cpp
datatype-restricted/rm/video/codec/g2mp4combo/common/csbsx.cpp

Index: common/c3bsx.cpp
===================================================================
RCS file: /cvsroot/rarvcode-mpeg4combo/codec/g2mp4combo/common/c3bsx.cpp,v
retrieving revision 1.5.12.2
diff -u -w -r1.5.12.2 c3bsx.cpp
--- common/c3bsx.cpp    23 Oct 2009 10:37:47 -0000  1.5.12.2
+++ common/c3bsx.cpp    27 Sep 2010 03:47:59 -0000
@@ -3788,8 +3788,9 @@
        // Get macro-block address
        *iSliceMBA = GetBits(m_mbaSize);

-       if (bFirst && *iSliceMBA)
-           bFirst = FALSE;
+       //for some videos, the start MB address of the first slice can be non-zero
+       /*if (bFirst && *iSliceMBA)
+           bFirst = FALSE;*/

        if (bFirst)
        {
Index: dec/d3mvdec.cpp
===================================================================
RCS file: /cvsroot/rarvcode-mpeg4combo/codec/g2mp4combo/dec/d3mvdec.cpp,v
retrieving revision 1.3.18.2
diff -u -w -r1.3.18.2 d3mvdec.cpp
--- dec/d3mvdec.cpp 5 Aug 2010 16:42:54 -0000   1.3.18.2
+++ dec/d3mvdec.cpp 27 Sep 2010 03:47:59 -0000
@@ -3376,19 +3376,8 @@
                m_BitCounters[BC_SLICE_HEADERS] += (m_pBitStream->GetBsOffset() - uBitOffset);
 #endif

-                   if (bFirstSlice && !iSliceMBA)
-                   {
                        m_iGQuant = m_iPQuant;
-                       // m_iPQuant == 0 has been caught before.
-                   }
-                   else
-                   {
-                       if(!iSQUANT) iSQUANT =1;
-                       m_iPQuant = m_iGQuant = iSQUANT;
-                   }
-
                    bFirstSlice = FALSE;
-                   iMBA = iSliceMBA;

                    // Set iLeft to one if this is the first MB for the slice.
                    GOBEdges.iLeft = 1;

________________________________________
From: Renjie Huang
Sent: Friday, September 24, 2010 5:19 PM
To: helix-client-dev@helixcommunity.org
Subject: CR: Bug 11047 H263+ clips cause SIGABORT due to memory corruption

Date: 2010-09-24
Project: RealPlayer for Android Smartphones

Synopsis: H263+ clips cause SIGABORT due to memory corruption

Overview: In my test, some H263+ clips cause SIGABORT during playback. The reason is that in slice structure mode, the micro block index iMBA read from the slice header exceed the valid range and corrupt the memory.  The clips for testing are created by the SUPER video converter, which uses FFmpeg.  The comparison among Helix h263 decoder, FFmpeg h263 decoder and the ITU H263 document show that FFmpeg does not strictly follow the picture header structure format of the ITU H263 for extended type.  In FFmpeg, the SQUANT field is right after the SSS field (ituh263dec.cpp: line 1072). It also ignores the MBA value.  In ITU 263,  the fields after SSS are "ELNUM RLNUM" (page 162); the SQUANT is after fields "MBA SEPB2" (page 96). In the CR, the decoder return PIA_S_UNSUPPORTED instead of continuing when iMBA exceeds valid range.

Reference:
  ITU H263 doc: http://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-H.263-200501-I!!PDF-E&type=items
  FFmpeg ituh263dec.cpp: http://git.ffmpeg.org/?p=ffmpeg;a=blob;f=libavcodec/ituh263dec.c;h=8b5d9391b2e196b6767848660ecbc93497d337b8;hb=HEAD

Changed files:
datatype-restricted/rm/video/codec/g2mp4combo/dec/d3mvdec.cpp

Image Size and Heap Use impact (Client -Only):
None

Platforms and Profiles Affected:
Platform: : head, 361, and 362
Profile: helix-client-android

Distribution Libraries Affected:
NA

Distribution library impact and planned action:
NA

Platforms and Profiles Build Verified:
Platform: hxclient_3_6_1_atlas
Profile:  helix-client-android

Platforms and Profiles Functionality verified:
Platform: hxclient_3_6_1_atlas
Profile: helix-client-android


Copyright assignment: I am a RealNetworks employee or contractor
-------------- next part --------------
A non-text attachment was scrubbed...
Name: h263-new.diff
Type: text/x-patch
Size: 1717 bytes
Desc: h263-new.diff
Url : http://lists.helixcommunity.org/pipermail/helix-client-dev/attachments/20100927/a05b0192/h263-new.bin
From rhuang at real.com  Mon Sep 27 11:36:53 2010
From: rhuang at real.com (Renjie Huang)
Date: Mon Sep 27 17:56:57 2010
Subject: [Helix-client-dev] a question on checking in code
Message-ID: <766B5A29D28DA442AB229AAEE2AFC44508043BEB3A@SEAMBX.corp.real.com>

Hi all

The current policy of checking in code is a bit confusing. It is not clear which branches we should apply the patch when fixing a bug or add a new feature.  According to Jim and Sheldon, the goal of  helix client will maintain only one branch 310,  and branch off when we are approaching product release and need stability. Can we make it a rule that all patches should be apply to HEAD and 310 branch? Thanks.
From jgordon at real.com  Mon Sep 27 12:25:05 2010
From: jgordon at real.com (Jamie Gordon)
Date: Mon Sep 27 18:45:19 2010
Subject: [Helix-client-dev] Re: [Android-port-dev] a question on checking in
	code
In-Reply-To: <766B5A29D28DA442AB229AAEE2AFC44508043BEB3A@SEAMBX.corp.real.com>
References: <766B5A29D28DA442AB229AAEE2AFC44508043BEB3A@SEAMBX.corp.real.com>
Message-ID: <4CA0FDA1.7090106@real.com>

All changes that are made on a branch should *always* go into the HEAD
and active parent branches (e.g. atlas-3.6.3 is a child of atlas-3.1.0,
so all changes to 363 are to be checked into the head and 310).

Thanks,
Jamie

On 9/27/2010 12:36 PM, Renjie Huang wrote:
> Hi all
>
> The current policy of checking in code is a bit confusing. It is not
> clear which branches we should apply the patch when fixing a bug or
> add a new feature.  According to Jim and Sheldon, the goal of  helix
> client will maintain only one branch 310,  and branch off when we are
> approaching product release and need stability. Can we make it a rule
> that all patches should be apply to HEAD and 310 branch? Thanks.
> _______________________________________________ Android-port-dev
> mailing list Android-port-dev@lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/android-port-dev

 

Site Map   |   Terms of Use   |   Privacy Policy   |   Contact Us

Copyright © 1995-2007 RealNetworks, Inc. All rights reserved. RealNetworks and Helix are trademarks of RealNetworks.
All other trademarks or registered trademarks are the property of their respective holders.