RE: [Re-Send] Add power save mode support for offload music playback (Framework part only)

"Zhao, Halley" <[email protected]> Thu, 17 Sep 2009 18:48:28 +0800
Newsgroups gmane.comp.multimedia.helix.devel
Message-ID <8FED46E8A9CA574792FC7AACAC38FE770286F59A8B@PDSMSX501.ccr.corp.intel.com>
Thanks Sheldon.
Here is my follow up

1. Move pIPowerSave to be a class member variable m_ pIPowerSave, and release it during class destroy. (CHXClientEngine.cpp and hxaudply.cpp)
2,3,4,5 followed your suggestion.
6. use base class HXSource for cast, and add 	HXNetSource with:        virtual HXBOOL UsesNetworkAccess(){return TRUE;} ;


-----Original Message-----
From: Sheldon fu [mailto:[email protected]] 
Sent: Tuesday, September 01, 2009 4:42 AM
To: Zhao, Halley
Cc: '[email protected]'
Subject: Re: [Helix-client-dev] [Re-Send] Add power save mode support for offload music playback (Framework part only)

1. pIPowerSave needs to be released in the new methods added to
CHXClientEngine.cpp.

2. Can not return HXR_FAIL from methods with HXBOOL (or anything other
than HX_RESULT) return type, in file CHXClientEngine.cpp.

3. STDMETHODIMP_ shouldn't be used in the header file CHXClientEngine.h.
Should just use STDMETHOD or STDMETHOD_

4. In hxcore.h, "STDMETHOD_(HX_RESULT,xxx)" should be just
"STDMETHOD(xxx)".

5. In hxcleng.cpp

+        LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
+        if (lPosition != NULL)
+        {
+            HXPlayer* pPlayer = (HXPlayer*)
m_PlayerList.GetAt(lPosition);
+            if (pPlayer != NULL)
+                pPlayer->AdjustWakeUpInterval(m_ulWakeUpInterval);

can be simplified by using m_PlayerList.GetHead or
m_PlayerList.GetTail().

6. Helix coding convention normally suggests putting body of conditional
statements in '{}' pair, at least in the client core source files. e.g, 

+    if (theErr == HXR_OK)
+        m_bInPowerSave = TRUE;
+    else
+        EndPowerSave();

would be

+    if (theErr == HXR_OK)
+    {
+        m_bInPowerSave = TRUE;
+    }
+    else
+    {
+        EndPowerSave();
+    }

7. in hxplay.cpp

+            if (((HXFileSource*)pSource)->UsesNetworkAccess())

is dangerous. You may be casting a HXNetSource to HXFileSource.

The overall logic looks ok to me.

I assume this is un-tested code since we don't have any audio renderer
that supports IHXPowerSave interface and behavior yet, right?

fxd

On Fri, 2009-08-28 at 10:21 +0800, Zhao, Halley wrote:
> Send it again since there is no response yet.
> 
>  
> 
>                                    
> ______________________________________________________________________
> From:[email protected]
> [mailto:[email protected]] On Behalf Of
> Zhao, Halley
> Sent: 2009年8月20日15:09
> To: '[email protected]'
> Subject: [Helix-client-dev] Add power save mode support for offload
> music playback (Framework part only)
> 
> 
>  
> 
> Synopsis: 
> 
> Some audio dsp could playback(decode and render) long period of audio
> data without interaction with Helix core.
> 
> we need reduce wakeup from Helix audio service to achieve power
> saving.
> 
> This is achieved by:
> 
>     audio codec/render doesn't register audio stream to audio service
> idle.
> 
>     audio codec/render register as a IHXClockSource to drive the
> timeline
> 
>                                
> 
> Overview: 
> 
>     Details see attached design-note.txt
> 
>          
> 
> Files Added:
> 
>        No file added
> 
> Files Modified:
> 
> |-- client
> 
> |   |-- audiosvc
> 
> |   |   |-- hxaudply.cpp
> 
> |   |   |-- hxaudses.cpp
> 
> |   |   `-- pub
> 
> |   |       |-- hxaudply.h
> 
> |   |       `-- hxaudses.h
> 
> |   `-- core
> 
> |       |-- hxbsrc.h
> 
> |       |-- hxcleng.cpp
> 
> |       |-- hxflsrc.cpp
> 
> |       |-- hxflsrc.h
> 
> |       |-- hxplay.cpp
> 
> |       `-- pub
> 
> |           |-- hxcleng.h
> 
> |           `-- hxplay.h
> 
> |-- common
> 
> |   `-- include
> 
> |       |-- hxausvc.h
> 
> |       |-- hxcore.h
> 
> |       `-- hxevent.h
> 
> |-- list.txt
> 
> `-- player
> 
>     `-- hxclientkit
> 
>         |-- pub
> 
>         |   `-- HXClientCFuncs.h
> 
>         `-- src
> 
>             |-- CHXClientEngine.cpp
> 
>             |-- CHXClientEngine.h
> 
>             `-- HXClientCFuncs.cpp
> 
>  
> 
> Image Size and Heap Use impact (Client -Only):
> 
>     little
> 
> Platforms and Profiles Affected:
> 
>     platform:   linux-2.2-libc6-gcc32-i586
> 
>     profile:    helix-client-all-defines
> 
>  
> 
> Distribution Libraries Affected:
> 
>     <hxmedpcleng.so>
> 
> Distribution library impact and planned action:
> 
>     <None>
> 
> Platforms and Profiles Build Verified:
> 
>     Set BIF branch  -> realplay_gtk_atlas_restricted
> 
>     Set Target(s)   -> player_all
> 
>     Set Profile     -> helix-client-moblin
> 
>     System ID       -> linux-2.2-libc6-gcc32-i586
> 
> Branch: 
> 
>     HEAD
> 
> Copyright assignment: <MUST be one of the following statements >
> 
>    2.      Intel has signed and delivered a Joint Copyright Assignment
> 
>            to RealNetworks, and received acknowledgment that the 
> 
>            agreement was received. 
> 
> Files Attached:
> 
> Design-note.txt, client-audiosvc.diff.txt, client-core.diff.txt,
> common-include.diff.txt, player-hxclientkit.diff.txt
> 
>  
> 
>  
> 
> ZHAO, Halley (Aihua)
> 
> Email: [email protected]
> 
> Tel: +86(21)61166476
> 
> iNet: 8821-6476
> 
> SSG/OTC/Moblin 3W038 Pole: F4
> 
> 
>  
> 
> 
> _______________________________________________
> Helix-client-dev mailing list
> [email protected]
> http://lists.helixcommunity.org/mailman/listinfo/helix-client-dev

_______________________________________________
Helix-client-dev mailing list
[email protected]
http://lists.helixcommunity.org/mailman/listinfo/helix-client-dev
client-audiosvc.diff.txt (text/plain, 11.2 KB)
Index: hxaudply.cpp
===================================================================
RCS file: /cvsroot/client/audiosvc/hxaudply.cpp,v
retrieving revision 1.56.2.2
diff -u -w -r1.56.2.2 hxaudply.cpp
--- hxaudply.cpp	23 Jul 2009 20:34:59 -0000	1.56.2.2
+++ hxaudply.cpp	17 Sep 2009 08:58:59 -0000
@@ -151,6 +151,10 @@
 ,       m_pActiveClockSource(NULL)
 ,       m_pLastMappingStream(NULL)
 ,       m_bNewMapStarting(TRUE)    
+#if defined(HELIX_FEATURE_POWER_SAVE)
+,	    m_bInPowerSave(FALSE)
+,       m_pRendererPowerSave(NULL)
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 {
 #ifdef HELIX_FEATURE_VOLUME
     m_pPlayerVolume = NULL;
@@ -248,6 +252,14 @@
     ClearClockSourceQueue();
     // Delete the inactive clock source queue
     HX_DELETE(m_pInactiveClockSourceQueue);
+
+    
+#if defined(HELIX_FEATURE_POWER_SAVE)
+        if(m_pRendererPowerSave)
+        {
+            HX_RELEASE(m_pRendererPowerSave);
+        }
+#endif    
 }
 
 /////////////////////////////////////////////////////////////////////////
@@ -3008,3 +3020,106 @@
     }
     return pStream1;
 }
+
+#if defined(HELIX_FEATURE_POWER_SAVE)
+HX_RESULT CHXAudioPlayer::RetrieveRendererPowerSave() {
+    if (m_pRendererPowerSave != NULL)
+    {
+        return HXR_OK;
+    }
+
+    if (m_pActiveClockSource != NULL &&
+        (m_pActiveClockSource->QueryInterface(IID_IHXPowerSave, (void**) &m_pRendererPowerSave) == HXR_OK))
+    {
+        return HXR_OK;
+    }
+
+    m_pRendererPowerSave = NULL;
+    return HXR_FAIL;
+}
+
+/* IHXPowerSave methods */
+STDMETHODIMP CHXAudioPlayer::StartPowerSave (void)
+{
+    HX_RESULT theErr = HXR_FAIL;
+    if (IsInPowerSave())
+    {
+        return HXR_FAIL;
+    }
+
+    if (!CanStartPowerSave())
+    {
+        return HXR_FAIL;
+    }
+
+    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
+    {
+        theErr = m_pRendererPowerSave->StartPowerSave();
+    }
+
+    if (theErr == HXR_OK)
+    {
+        m_bInPowerSave = TRUE;
+    }
+
+    return theErr;
+}
+
+STDMETHODIMP CHXAudioPlayer::EndPowerSave (void)
+{
+    HX_RESULT theErr = HXR_FAIL;
+    if (!IsInPowerSave())
+    {
+        return HXR_FAIL;
+    }
+
+    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
+    {
+        theErr = m_pRendererPowerSave->EndPowerSave();
+    }
+
+    if (theErr == HXR_OK)
+    {
+        m_bInPowerSave = FALSE;
+        m_pRendererPowerSave = NULL;
+    }
+    return theErr;
+}
+
+STDMETHODIMP_(HXBOOL) CHXAudioPlayer::IsInPowerSave (void)
+{
+    return m_bInPowerSave;
+}
+
+STDMETHODIMP_(HXBOOL) CHXAudioPlayer::CanStartPowerSave (void)
+{
+    if (m_bHasStreams)
+    {
+        return FALSE;
+    }
+
+    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
+    {
+        return m_pRendererPowerSave->CanStartPowerSave();
+    }
+
+    return FALSE;
+}
+
+STDMETHODIMP_(ULONG32) CHXAudioPlayer::GetWakeUpInterval (void)
+{
+    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
+    {
+        return m_pRendererPowerSave->GetWakeUpInterval();
+    }
+}
+
+STDMETHODIMP_(ULONG32) CHXAudioPlayer::SetWakeUpInterval (ULONG32 /*IN*/ ulWakeUpInterval)
+{
+    if (RetrieveRendererPowerSave() == HXR_OK && m_pRendererPowerSave != NULL)
+    {
+        return m_pRendererPowerSave->SetWakeUpInterval(ulWakeUpInterval);
+    }
+}
+
+#endif /*HELIX_FEATURE_POWER_SAVE*/
Index: hxaudses.cpp
===================================================================
RCS file: /cvsroot/client/audiosvc/hxaudses.cpp,v
retrieving revision 1.79.2.6
diff -u -w -r1.79.2.6 hxaudses.cpp
--- hxaudses.cpp	26 Jul 2009 01:56:40 -0000	1.79.2.6
+++ hxaudses.cpp	17 Sep 2009 08:59:00 -0000
@@ -232,6 +232,9 @@
     , m_uVolume(HX_INIT_VOLUME)
     , m_bMute(FALSE)
     , m_bProcessingDeviceVolumeChange(FALSE) 
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    , m_bInPowerSave(FALSE)
+#endif /*HELIX_FEATURE_POWER_SAVE*/
     , m_dBufEndTime((double) 0.)
     , m_bDisableWrite(FALSE)
     , m_bInPlayAudio(FALSE)
@@ -1898,7 +1901,7 @@
         if (bBitConversion && bChannelConversion)
         {
             // Code problem from 1997:
-            // Warning: operation on ‘pShortBuf’ may be undefined
+            // Warning: operation on ‘pShortBufâ€?may be undefined
             *pOutUCharBuf++ = (UCHAR)   (
                 ((LONG32) ((*pShortBuf++  + 32768L) >> 8) +
                  (LONG32) ((*pShortBuf++  + 32768L) >> 8))/2
@@ -1911,7 +1914,7 @@
         else /*if (!bBitConversion && bChannelConversion) */
         {
             // Code problem from 1997:
-            // Warning: operation on ‘pShortBuf’ may be undefined
+            // Warning: operation on ‘pShortBufâ€?may be undefined
             *pOutShortBuf++ = (short int) (((LONG32) *pShortBuf++  + (LONG32) *pShortBuf++)/2);
         }
     }
@@ -4603,3 +4606,103 @@
         }
     }
 }
+
+#if defined(HELIX_FEATURE_POWER_SAVE)
+/* IHXPowerSave methods */
+STDMETHODIMP_(HX_RESULT) CHXAudioSession::StartPowerSave (void)
+{
+    HX_RESULT theErr = HXR_FAIL;
+    if (IsInPowerSave())
+    {
+        return HXR_FAIL;
+    }
+
+    if (!CanStartPowerSave())
+    {
+        return HXR_FAIL;
+    }
+
+
+    if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+    {
+        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+        theErr = pPlayer->StartPowerSave();
+    }
+
+    if (theErr == HXR_OK)
+    {
+        m_bInPowerSave = TRUE;
+    }
+
+    return theErr;
+}
+
+STDMETHODIMP_(HX_RESULT) CHXAudioSession::EndPowerSave (void)
+{
+    HX_RESULT theErr = HXR_FAIL;
+    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();
+    }
+
+    if (theErr == HXR_OK)
+    {
+        m_bInPowerSave = FALSE;
+    }
+
+    return theErr;
+}
+
+STDMETHODIMP_(HXBOOL) CHXAudioSession::IsInPowerSave (void)
+{
+    return m_bInPowerSave;
+}
+
+STDMETHODIMP_(HXBOOL) CHXAudioSession::CanStartPowerSave (void)
+{
+    if (m_bHasStreams)
+    {
+        return FALSE;
+    }
+
+    if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+    {
+        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+        return pPlayer->CanStartPowerSave();
+    }
+
+    return FALSE;
+}
+
+STDMETHODIMP_(ULONG32) CHXAudioSession::GetWakeUpInterval (void)
+{
+    if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+    {
+        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+        return pPlayer->GetWakeUpInterval();
+    }
+    return 0;
+}
+
+STDMETHODIMP_(ULONG32) CHXAudioSession::SetWakeUpInterval (ULONG32 /*IN*/ ulWakeUpInterval)
+{
+    if (m_pPlayerList && m_pPlayerList->GetCount() == 1)
+    {
+        CHXSimpleList::Iterator lIter = m_pPlayerList->Begin();
+        CHXAudioPlayer* pPlayer = (CHXAudioPlayer*) (*lIter);
+        return pPlayer->SetWakeUpInterval(ulWakeUpInterval);
+    }
+    return 0;
+}
+
+#endif /*HELIX_FEATURE_POWER_SAVE*/
Index: pub/hxaudply.h
===================================================================
RCS file: /cvsroot/client/audiosvc/pub/hxaudply.h,v
retrieving revision 1.21
diff -u -w -r1.21 hxaudply.h
--- pub/hxaudply.h	6 Jul 2007 21:57:40 -0000	1.21
+++ pub/hxaudply.h	17 Sep 2009 08:59:00 -0000
@@ -65,6 +65,10 @@
 struct IHXPreferences;
 struct IHXAudioCrossFade;
 
+#if defined(HELIX_FEATURE_POWER_SAVE)
+_INTERFACE IHXPowerSave;
+#endif // HELIX_FEATURE_POWER_SAVE
+
 typedef struct _HXAudioFormat HXAudioFormat;
 
 class CHXAudioSession;
@@ -93,6 +97,9 @@
 #ifdef HELIX_FEATURE_VOLUME 
 		      public IHXVolumeAdviseSink,
 #endif 
+#ifdef HELIX_FEATURE_POWER_SAVE
+		      public IHXPowerSave,
+#endif
 		      public IHXAudioCrossFade,
 		      public IHXCallback,
 		      public IHXPlaybackVelocity,
@@ -154,6 +161,11 @@
     CHXAudioStream* m_pLastMappingStream;
     HXBOOL          m_bNewMapStarting;
     
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    HXBOOL          m_bInPowerSave;         // Player in power save mode
+    IHXPowerSave*   m_pRendererPowerSave;
+#endif /*HELIX_FEATURE_POWER_SAVE*/
+
   protected:
     ~CHXAudioPlayer();
 
@@ -215,6 +227,18 @@
         
 #endif        
         
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    HX_RESULT RetrieveRendererPowerSave();
+    /* 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 );
+#endif /*HELIX_FEATURE_POWER_SAVE*/
+
+        
     /************************************************************************
      *  Method:
      *      IHXAudioPlayer::GetAudioStreamCount
Index: pub/hxaudses.h
===================================================================
RCS file: /cvsroot/client/audiosvc/pub/hxaudses.h,v
retrieving revision 1.31.2.2
diff -u -w -r1.31.2.2 hxaudses.h
--- pub/hxaudses.h	23 Jul 2009 20:35:04 -0000	1.31.2.2
+++ pub/hxaudses.h	17 Sep 2009 08:59:00 -0000
@@ -57,7 +57,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #endif
-
+#include "hxcore.h"
 //  IHXTimelineWatcher defines.
 #  define TLW_PAUSE    1
 #  define TLW_RESUME   2
@@ -115,6 +115,10 @@
 struct IHXAudioHook;
 struct IHXInterruptState;
 
+#if defined(HELIX_FEATURE_POWER_SAVE)
+_INTERFACE IHXPowerSave;
+#endif // HELIX_FEATURE_POWER_SAVE
+
 typedef struct _HXAudioFormat HXAudioFormat;
 class CHXAudioPlayer;
 
@@ -145,6 +149,9 @@
 #ifdef HELIX_FEATURE_VOLUME                          
     public IHXVolumeAdviseSink,
 #endif                          
+#ifdef HELIX_FEATURE_POWER_SAVE
+		      public IHXPowerSave,
+#endif
     public IHXCallback,
     public IHXAudioResamplerManager,
     public IHXAudioPushdown2,
@@ -370,6 +377,19 @@
                                          HXBOOL&     /*OUT*/    bChanged
                                          );
 
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    /* 
+     * 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 );
+#endif /*HELIX_FEATURE_POWER_SAVE*/
+
+
     /*
      *  IHXAudioDeviceManager2 methods
      */
@@ -688,6 +708,10 @@
     HXBOOL                  m_bMute;                // the mute state
     HXBOOL                  m_bProcessingDeviceVolumeChange;
 
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    HXBOOL                  m_bInPowerSave;         // Player in power save mode
+#endif /*HELIX_FEATURE_POWER_SAVE*/
+
     /*
      * Continuous session play back time. This is the time written to the audio
      * device object for each buffer. This is the time that each audio player
client-core.diff.txt (text/plain, 12 KB)
Index: hxbsrc.h
===================================================================
RCS file: /cvsroot/client/core/hxbsrc.h,v
retrieving revision 1.58.2.1
diff -u -w -r1.58.2.1 hxbsrc.h
--- hxbsrc.h	17 Oct 2007 04:46:31 -0000	1.58.2.1
+++ hxbsrc.h	17 Sep 2009 08:57:24 -0000
@@ -876,6 +876,7 @@
 
             virtual HXBOOL IsPacketlessSource() { return FALSE; }
 
+            virtual HXBOOL UsesNetworkAccess()  { return TRUE; }
 #if defined(HELIX_FEATURE_DRM)
 
             virtual HXBOOL IsHelixDRMProtected(void) {return m_bIsProtected;}
Index: hxcleng.cpp
===================================================================
RCS file: /cvsroot/client/core/hxcleng.cpp,v
retrieving revision 1.125.2.8
diff -u -w -r1.125.2.8 hxcleng.cpp
--- hxcleng.cpp	6 Jul 2009 18:08:35 -0000	1.125.2.8
+++ hxcleng.cpp	17 Sep 2009 08:57:25 -0000
@@ -209,6 +209,7 @@
 #endif /*defined (_WINDOWS) || defined (_WIN32)*/
 
 #include "hxver.h"
+#include "hxevent.h"
 
 #ifdef _OPENWAVE
 #include "timeline.h"
@@ -387,6 +388,10 @@
 #endif /*HELIX_FEATURE_SYSTEM_EXTERNAL_TIMER*/
 
 ,m_pContext(NULL)
+#if defined(HELIX_FEATURE_POWER_SAVE)
+,m_bInPowerSave(FALSE)
+,m_ulWakeUpInterval(DEFAULT_WAKEUP_INTERVAL)
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 {
 #if 0 // XXX HP Atlas
 #if defined(HELIX_FEATURE_PREFERENCES)
@@ -1114,7 +1119,9 @@
 #endif /*HELIX_FEATURE_SYSTEM_EXTERNAL_TIMER*/
 
         { GET_IIDHANDLE(IID_IHXAutoBWCalibrationAdviseSink), (IHXAutoBWCalibrationAdviseSink*)this },
-	{ GET_IIDHANDLE(IID_IHXContextUser), (IHXContextUser*)this }
+	{ GET_IIDHANDLE(IID_IHXContextUser), (IHXContextUser*)this },
+// #ifdef..
+	{ GET_IIDHANDLE(IID_IHXPowerSave), (IHXPowerSave*)this }
     };
     HX_RESULT retval = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
     if (retval == HXR_OK)
@@ -1631,6 +1638,23 @@
 #endif //HELIX_FEATURE_NETSERVICES
 #endif  // __TCS__
 
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    if (!pEvent)
+    {
+        return HXR_OK;
+    }
+
+    if (pEvent->event == HX_POWERSAVE_ON)
+    {
+        return StartPowerSave();
+    }
+    else if (pEvent->event == HX_POWERSAVE_OFF)
+    {
+        return EndPowerSave();
+    }
+
+#endif // HELIX_FEATURE_POWER_SAVE
+
     return HXR_OK;
 }
 
@@ -3130,5 +3154,105 @@
 }
 #endif /*HELIX_FEATURE_SYSTEM_EXTERNAL_TIMER*/
 
+#if defined(HELIX_FEATURE_POWER_SAVE)
+STDMETHODIMP_(HX_RESULT) HXClientEngine::StartPowerSave(void)
+{
+    HX_RESULT theErr = HXR_OK;
+
+    if (!CanStartPowerSave())
+    {
+        return HXR_FAIL;
+    }
+
+    if (m_pAudioSession)
+    {
+        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)
+        {
+            pPlayer->AdjustWakeUpInterval(m_ulWakeUpInterval);
+        }
+    }
+
+    if (theErr == HXR_OK)
+    {
+        m_bInPowerSave = TRUE;
+    }
+    else
+    {
+        EndPowerSave();
+    }
+
+    return theErr;
+}
+
+STDMETHODIMP_(HX_RESULT) HXClientEngine::EndPowerSave(void)
+{
+    HX_RESULT theErr = HXR_OK;
+
+    if (!IsInPowerSave())
+    {
+        return HXR_FAIL;
+    }
+
+    if (m_pAudioSession)
+    {
+        theErr = m_pAudioSession->EndPowerSave();
+    }
+
+    if (theErr == HXR_OK)
+    {
+        m_bInPowerSave = FALSE;
+    }
+
+    return theErr;
+}
+
+STDMETHODIMP_(HXBOOL) HXClientEngine::IsInPowerSave(void)
+{
+    return m_bInPowerSave;
+}
+
+STDMETHODIMP_(HXBOOL) HXClientEngine::CanStartPowerSave(void)
+{
+    if ((GetPlayerCount() > 1) || m_bInPowerSave)
+    {
+        return FALSE;
+    }
+
+    LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
+    if (lPosition != NULL)
+    {
+        HXPlayer* pPlayer = (HXPlayer*) m_PlayerList.GetAt(lPosition);
+        if (pPlayer != NULL && !pPlayer->IsLocalSource())
+        {
+            return FALSE;
+        }
+    }
+
+    if (m_pAudioSession)
+    {
+        return m_pAudioSession->CanStartPowerSave();
+    }
+
+    return FALSE;
+}
+
+STDMETHODIMP_(ULONG32) HXClientEngine::GetWakeUpInterval(void)
+{
+    return m_ulWakeUpInterval;
+}
+
+STDMETHODIMP_(ULONG32) HXClientEngine::SetWakeUpInterval( ULONG32 /*IN*/ ulWakeUpInterval)
+{
+    m_ulWakeUpInterval = ulWakeUpInterval;
+
+    return m_ulWakeUpInterval;
+}
 
+#endif /*HELIX_FEATURE_POWER_SAVE*/
Index: hxflsrc.cpp
===================================================================
RCS file: /cvsroot/client/core/hxflsrc.cpp,v
retrieving revision 1.126.2.3
diff -u -w -r1.126.2.3 hxflsrc.cpp
--- hxflsrc.cpp	15 Sep 2008 06:01:40 -0000	1.126.2.3
+++ hxflsrc.cpp	17 Sep 2009 08:57:25 -0000
@@ -3895,6 +3895,39 @@
 }
 
 HXBOOL	
+HXFileSource:: UsesNetworkAccess( void )
+{
+    HXBOOL bUsesNetwork = FALSE;
+
+    if (m_pFFObject)
+    {
+        IHXAdvise* pFFAdvise = NULL;
+
+         if (SUCCEEDED(m_pFFObject->QueryInterface(IID_IHXAdvise, (void **) &pFFAdvise)))
+        {
+                 HX_RESULT adviseStatus = pFFAdvise->Advise(HX_FILERESPONSEADVISE_NETWORKACCESS);
+                  if (adviseStatus == HXR_ADVISE_NETWORK_ACCESS)
+                 {
+                      bUsesNetwork = TRUE;
+                 }
+        }
+
+         HX_RELEASE(pFFAdvise);
+    }
+
+    if (m_pFileObject && !bUsesNetwork)
+    {
+        HX_RESULT adviseStatus = m_pFileObject->Advise(HX_FILEADVISE_NETWORKACCESS);
+             if (adviseStatus == HXR_ADVISE_NETWORK_ACCESS)
+             {
+                 bUsesNetwork = TRUE;
+             }
+    }
+
+    return bUsesNetwork;
+}
+
+HXBOOL	
 HXFileSource::ShouldDisableFastStart(void)
 {
     HXBOOL bCheckBandwidth = FALSE;
Index: hxflsrc.h
===================================================================
RCS file: /cvsroot/client/core/hxflsrc.h,v
retrieving revision 1.36.2.1
diff -u -w -r1.36.2.1 hxflsrc.h
--- hxflsrc.h	15 Sep 2008 06:02:28 -0000	1.36.2.1
+++ hxflsrc.h	17 Sep 2009 08:57:25 -0000
@@ -342,6 +342,7 @@
 
     virtual HX_RESULT	FillRecordControl(UINT32 ulLoopEntryTime = 0);
     virtual HXBOOL      IsPacketlessSource() { return m_bPacketlessSource; }
+    virtual HXBOOL UsesNetworkAccess() ;
     virtual HXBOOL      ShouldDisableFastStart(void);
 protected:
     LONG32			m_lRefCount;
Index: hxntsrc.h
===================================================================
RCS file: /cvsroot/client/core/hxntsrc.h,v
retrieving revision 1.54.2.1
diff -u -w -r1.54.2.1 hxntsrc.h
--- hxntsrc.h	19 Jun 2008 22:52:57 -0000	1.54.2.1
+++ hxntsrc.h	17 Sep 2009 08:57:25 -0000
@@ -243,6 +243,7 @@
 		HX_RESULT	SetReconnectInfo(IHXValues* pValues);
 
 	        HXBOOL		IsSourceDone(void);
+	        virtual HXBOOL UsesNetworkAccess(){return TRUE;} ;
 
 		void		EnterBufferedPlay(void);
 		void		LeaveBufferedPlay(void);
Index: hxplay.cpp
===================================================================
RCS file: /cvsroot/client/core/hxplay.cpp,v
retrieving revision 1.185.2.12
diff -u -w -r1.185.2.12 hxplay.cpp
--- hxplay.cpp	6 Jul 2009 18:08:35 -0000	1.185.2.12
+++ hxplay.cpp	17 Sep 2009 08:57:27 -0000
@@ -431,6 +431,9 @@
     ,m_pSharedWallClocks(NULL)
     ,m_pRecordService(NULL)
     ,m_bRecordServiceEnabled(FALSE)
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    ,m_ulPlayerWakeUpInterval(0)
+#endif //HELIX_FEATURE_POWER_SAVE
     ,m_pMetaInfo(NULL)
     ,m_pEmbeddedUI(NULL)
 #if defined(HELIX_FEATURE_PROGRESSIVE_DOWNLD_STATUS)
@@ -11377,6 +11380,18 @@
     ulRet += ADDITIONAL_PREDELIVERY_TIME;
 #endif	// _MACINTOSH
 
+#if defined(HELIX_FEATURE_POWER_SAVE) && defined(HELIX_FEATURE_AUDIO)
+    if (m_pAudioPlayer && 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
+    }
+#endif // (HELIX_FEATURE_POWER_SAVE) && (HELIX_FEATURE_AUDIO)
+
     return ulRet;
 }
 
@@ -13876,3 +13891,22 @@
     }
 }
 
+HXBOOL HXPlayer::IsLocalSource()
+{
+    CHXMapPtrToPtr::Iterator iter = m_pSourceMap->Begin();
+    while(iter != m_pSourceMap->End())
+    {
+        SourceInfo* pSourceInfo = (SourceInfo*)(*iter);
+        HX_ASSERT (pSourceInfo != NULL);
+        HXSource* pSource = pSourceInfo->m_pSource;
+        if (pSource != NULL)
+        {
+            if (((HXSource*)pSource)->UsesNetworkAccess())
+            {
+                return FALSE;
+            }
+        }
+        ++iter;
+    }
+    return TRUE;
+}
Index: pub/hxcleng.h
===================================================================
RCS file: /cvsroot/client/core/pub/hxcleng.h,v
retrieving revision 1.45.2.3
diff -u -w -r1.45.2.3 hxcleng.h
--- pub/hxcleng.h	28 Jul 2009 22:41:09 -0000	1.45.2.3
+++ pub/hxcleng.h	17 Sep 2009 08:57:27 -0000
@@ -141,6 +141,10 @@
 #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
 {
@@ -205,6 +209,9 @@
         , public IHXMacBlitMutex
 #endif
         , public CHXBaseCountingObject
+#if defined(HELIX_FEATURE_POWER_SAVE)
+        , public IHXPowerSave
+#endif //HELIX_FEATURE_POWER_SAVE
 {
 protected:
     LONG32		    m_lRefCount;
@@ -618,6 +625,18 @@
     STDMETHOD_(ULONG32,GetCurrentClock)	(THIS_ HXTimeval* pCurTime);
 #endif /*HELIX_FEATURE_SYSTEM_EXTERNAL_TIMER*/
 
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    /*
+     * 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 );
+#endif /*HELIX_FEATURE_POWER_SAVE*/
+
 
     STDMETHOD(StopAudioPlayback)	(THIS);
 
@@ -659,6 +678,10 @@
 #if defined(HELIX_FEATURE_SYSTEM_EXTERNAL_TIMER)
     HXTimeval*                    m_pCurrentTime;
 #endif /*HELIX_FEATURE_SYSTEM_EXTERNAL_TIMER*/
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    HXBOOL			m_bInPowerSave;
+    ULONG32			m_ulWakeUpInterval;
+#endif /*HELIX_FEATURE_POWER_SAVE*/
 
 };
 
Index: pub/hxplay.h
===================================================================
RCS file: /cvsroot/client/core/pub/hxplay.h,v
retrieving revision 1.64.2.3
diff -u -w -r1.64.2.3 hxplay.h
--- pub/hxplay.h	5 May 2009 16:47:54 -0000	1.64.2.3
+++ pub/hxplay.h	17 Sep 2009 08:57:27 -0000
@@ -215,6 +215,7 @@
 /* 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;
@@ -1632,6 +1633,19 @@
     STDMETHOD(UpdateVelocity)     (THIS_ INT32 lVelocity);
     STDMETHOD(UpdateKeyFrameMode) (THIS_ HXBOOL bKeyFrameMode);
 
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    void AdjustWakeUpInterval(ULONG32 ulWakeUpInterval)
+    {
+        m_ulPlayerWakeUpInterval = ulWakeUpInterval;
+    }
+#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();
+
     ////////////////////////////////////////////////////////////////////
     //
     // The following members are related to meta-file support.
@@ -2228,6 +2242,10 @@
     IHXRecordService*	        m_pRecordService;
     HXBOOL                      m_bRecordServiceEnabled;
 
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    ULONG32                     m_ulPlayerWakeUpInterval;
+#endif
+
 #if defined(HELIX_FEATURE_PROGRESSIVE_DOWNLD_STATUS)
     UINT32              m_ulTotalDurReported;
     UINT32              m_ulTimeOfOpenURL;
common-include.diff.txt (text/plain, 6.9 KB)
Index: hxausvc.h
===================================================================
RCS file: /cvsroot/common/include/hxausvc.h,v
retrieving revision 1.19.2.1
diff -u -w -r1.19.2.1 hxausvc.h
--- hxausvc.h	23 Jul 2009 20:36:45 -0000	1.19.2.1
+++ hxausvc.h	17 Sep 2009 09:00:51 -0000
@@ -88,6 +88,7 @@
 typedef _INTERFACE   IHXDryNotification	    IHXDryNotification;
 typedef _INTERFACE   IHXBuffer			    IHXBuffer;
 typedef _INTERFACE   IHXValues			    IHXValues;
+typedef _INTERFACE   IHXPowerSave           IHXPowerSave;
 
 /****************************************************************************
  *
Index: hxcore.h
===================================================================
RCS file: /cvsroot/common/include/hxcore.h,v
retrieving revision 1.23
diff -u -w -r1.23 hxcore.h
--- hxcore.h	6 Jul 2007 20:43:41 -0000	1.23
+++ hxcore.h	17 Sep 2009 09:00:52 -0000
@@ -2395,6 +2395,98 @@
 
 };
 
+/****************************************************************************
+ *
+ *  Interface:
+ *
+ *      IHXPowerSave
+ *
+ *  Purpose:
+ *
+ *      Interface provided by the client engine for top layer player to inform 
+ *  the core to enter/exit/query power save mode.
+ *
+ *  IID_IHXPowerSave:
+ *
+ *      {F52067D2-BF0B-4081-B36F-CAEE7924219A}
+ *
+ */
+
+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)
@@ -2425,6 +2517,9 @@
 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: hxevent.h
===================================================================
RCS file: /cvsroot/common/include/hxevent.h,v
retrieving revision 1.10.2.1
diff -u -w -r1.10.2.1 hxevent.h
--- hxevent.h	14 Aug 2007 00:09:09 -0000	1.10.2.1
+++ hxevent.h	17 Sep 2009 09:00:52 -0000
@@ -444,10 +444,43 @@
 //			  is known to be available. FALSE if configuration
 //			  is known to exist but could not be obtained.
 
+
+//------------------------- SYSTEM EVENTS ----------------------------
+
+// This class of events are sent to client engine to notify them of system 
+// events. All system events have the event structure filled out as follows:
+//
+//    UINT32    event;
+//    void*     window;     null
+//    void*     param1;     null
+//    void*     param2;     null
+//    void*     result;     HRESULT result code of message handling
+//    HXBOOL    handled;    TRUE if handled, FALSE if not handled
+
+#define HX_SYSTEM_EVENT_CLASS    HX_BASE_EVENT + 0x00006000
+#define HX_POWERSAVE_ON          (HX_SYSTEM_EVENT_CLASS + 1)
+#define HX_POWERSAVE_OFF         (HX_SYSTEM_EVENT_CLASS + 2)
+
+// HX_POWERSAVE_ON indicates to client engine to start operating in power save
+// mode. Full system (hardware) transition to power save mode may follow at 
+// some later time based on set of criteria (e.g. audio device detected full to
+// certain level).  This event will // be marked as successfully handled if 
+// client engine can start operating in power save mode at the time of the 
+// event.  Otherwise, event will be marked as handled with failure status. 
+// Currently, it is expected that client engine will accept operation in power
+// save mode only if having one player object allocated and player object 
+// playing only one source with only one audio stream.
+
+// HX_POWERSAVE_OFF will indicate to client engine to start operating in normal
+// (non-power save) mode.  The action will be performed immediately.  This 
+// event will always be handled successfully unless a catastrophic failure 
+// occurs.
+
+
 // Each event class should have a comment describing the kinds
 // of events that belong to this class
 // The next event class should use this base:
-#define HX_NEXT_EVENT_CLASS    HX_BASE_EVENT + 0x00006000
+#define HX_NEXT_EVENT_CLASS    HX_BASE_EVENT + 0x00007000
 
 // $Private:
 #ifdef _WINDOWS
Index: platform.h
===================================================================
RCS file: /cvsroot/common/include/platform.h,v
retrieving revision 1.49.2.6
diff -u -w -r1.49.2.6 platform.h
--- platform.h	31 Aug 2009 05:06:29 -0000	1.49.2.6
+++ platform.h	17 Sep 2009 09:00:52 -0000
@@ -49,6 +49,7 @@
 
 #ifndef _PLATFORM_H_
 #define _PLATFORM_H_
+
 #define TARVER_STR_PLATFORM "linux-2.2-libc6-gcc32-i586"
-#define TARVER_STR_BUILD_BRANCH "hxclient_3_1_0_atlas"
+#define TARVER_STR_BUILD_BRANCH "realplay_gtk_atlas_restricted"
 #endif
player-hxclientkit.diff.txt (text/plain, 9 KB)
Index: pub/HXClientCFuncs.h
===================================================================
RCS file: /cvsroot/player/hxclientkit/pub/HXClientCFuncs.h,v
retrieving revision 1.23.2.8
diff -u -w -r1.23.2.8 HXClientCFuncs.h
--- pub/HXClientCFuncs.h	24 Aug 2009 04:56:10 -0000	1.23.2.8
+++ pub/HXClientCFuncs.h	17 Sep 2009 08:58:13 -0000
@@ -164,6 +164,15 @@
 UInt32 ClientPlayerGetSuperBufferSize( HXClientPlayerToken clientPlayerToken );
 bool ClientPlayerGetSuperbufferTimelineInfo(HXClientPlayerToken clientPlayerToken, UInt32 *pMinTime, UInt32 *pMinBuffered, UInt32 *pMaxSeekable, UInt32 *pMaxBuffered, UInt32 *pMaxTime);
 
+//power save interface
+bool ClientEngineStartPowerSave();
+bool ClientEngineEndPowerSave();
+bool ClientEngineIsInPowerSave();
+bool ClientEngineCanPowerSave();
+UInt32 ClientEngineGetWakeUpInterval();
+UInt32 ClientEngineSetWakeUpInterval(UInt32 interval);
+
+
 #ifdef __cplusplus
 }
 #endif
Index: src/CHXClientEngine.cpp
===================================================================
RCS file: /cvsroot/player/hxclientkit/src/CHXClientEngine.cpp,v
retrieving revision 1.8.2.2
diff -u -w -r1.8.2.2 CHXClientEngine.cpp
--- src/CHXClientEngine.cpp	11 Dec 2007 23:47:08 -0000	1.8.2.2
+++ src/CHXClientEngine.cpp	17 Sep 2009 08:58:13 -0000
@@ -66,6 +66,9 @@
 
 CHXClientEngine::CHXClientEngine( void )
 	: m_lCount( 0 )
+#if defined(HELIX_FEATURE_POWER_SAVE)
+        ,m_pIPowerSave(NULL)
+#endif	
 {
 }
 
@@ -77,6 +80,13 @@
 		m_SharedClientEngine = NULL;
 	}
 #endif
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    if(m_pIPowerSave)
+    {
+        HX_RELEASE(m_pIPowerSave);
+    }
+#endif    
+
 }
 
 bool
@@ -228,3 +238,126 @@
 	
 	return pIClientEngine->EventOccurred( pEvent );
 }
+
+#if defined(HELIX_FEATURE_POWER_SAVE)
+// power save interface
+HX_RESULT CHXClientEngine::StartPowerSave()
+{
+    IHXClientEngine* pIClientEngine = NULL;
+    pIClientEngine = GetClientEngine();
+    if ( !pIClientEngine )
+    {
+        return HXR_FAIL;
+    }
+
+    if(!m_pIPowerSave)
+    {
+        if(pIClientEngine->QueryInterface(IID_IHXPowerSave, (void**)&m_pIPowerSave) != HXR_OK)
+        {
+            return HXR_FAIL;
+        }
+    }    
+    
+    return m_pIPowerSave->StartPowerSave();
+
+}
+HX_RESULT CHXClientEngine::EndPowerSave()
+{
+    IHXClientEngine* pIClientEngine = NULL;
+    pIClientEngine = GetClientEngine();
+    if ( !pIClientEngine ) 
+    {
+        return HXR_FAIL;
+    }
+
+    if(!m_pIPowerSave)
+    {
+        if(pIClientEngine->QueryInterface(IID_IHXPowerSave, (void**)&m_pIPowerSave) != HXR_OK)
+        {
+            return HXR_FAIL;
+        }
+    }
+    
+    return m_pIPowerSave->EndPowerSave();
+
+}
+HXBOOL CHXClientEngine::IsInPowerSave()
+{
+    IHXClientEngine* pIClientEngine = NULL;
+    pIClientEngine = GetClientEngine();
+    if ( !pIClientEngine ) 
+    {
+        return FALSE;
+    }
+
+    if(!m_pIPowerSave)
+    {
+        if(pIClientEngine->QueryInterface(IID_IHXPowerSave, (void**)&m_pIPowerSave) != HXR_OK)
+        {
+            return FALSE;
+        }
+    }
+    
+    return m_pIPowerSave->IsInPowerSave();
+
+}
+HXBOOL CHXClientEngine::CanStartPowerSave ()
+{
+    IHXClientEngine* pIClientEngine = NULL;
+    pIClientEngine = GetClientEngine();
+    if ( !pIClientEngine ) 
+    {
+        return FALSE;
+    }
+
+    if(!m_pIPowerSave)
+    {
+        if(pIClientEngine->QueryInterface(IID_IHXPowerSave, (void**)&m_pIPowerSave) != HXR_OK)
+        {
+            return FALSE;
+        }
+    }    
+    
+    return m_pIPowerSave->CanStartPowerSave();
+}
+UInt32 CHXClientEngine::GetWakeUpInterval()
+{
+    IHXClientEngine* pIClientEngine = NULL;
+    pIClientEngine = GetClientEngine();
+    if ( !pIClientEngine ) 
+    {
+        return 0;
+    }
+    
+    if(!m_pIPowerSave)
+    {
+        if(pIClientEngine->QueryInterface(IID_IHXPowerSave, (void**)&m_pIPowerSave) != HXR_OK)
+        {
+            return 0;
+        }
+    }
+    
+    return m_pIPowerSave->GetWakeUpInterval();
+
+}
+ULONG32 CHXClientEngine::SetWakeUpInterval(UInt32 ulWakeUpInterval)
+{
+    IHXClientEngine* pIClientEngine = NULL;
+    pIClientEngine = GetClientEngine();
+    if ( !pIClientEngine ) 
+    {
+        return 0;
+    }
+
+    if(!m_pIPowerSave)
+    {
+        if(pIClientEngine->QueryInterface(IID_IHXPowerSave, (void**)&m_pIPowerSave) != HXR_OK)
+        {
+            return 0;
+        }
+    }
+    
+    return m_pIPowerSave->SetWakeUpInterval(ulWakeUpInterval);
+
+}
+#endif
Index: src/CHXClientEngine.h
===================================================================
RCS file: /cvsroot/player/hxclientkit/src/CHXClientEngine.h,v
retrieving revision 1.8
diff -u -w -r1.8 CHXClientEngine.h
--- src/CHXClientEngine.h	6 Jul 2007 20:50:04 -0000	1.8
+++ src/CHXClientEngine.h	17 Sep 2009 08:58:13 -0000
@@ -60,6 +60,9 @@
 #include "HXClientCallbacks.h"
 
 class CHXClientEngine : public IHXClientEngine
+#if defined(HELIX_FEATURE_POWER_SAVE)
+,public IHXPowerSave
+#endif
 {
 	HX_DECLARE_UNKNOWN_NOCREATE( CHXClientEngine )
 
@@ -97,6 +100,17 @@
 	STDMETHOD_( UINT16, GetPlayerCount ) ( THIS );
 	STDMETHOD ( GetPlayer ) ( THIS_ UINT16 nPlayerNumber, REF( IUnknown* ) pUnknown );
 	STDMETHOD ( EventOccurred ) ( THIS_ HXxEvent* pEvent );
+
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    IHXPowerSave * m_pIPowerSave;
+
+    STDMETHOD_(HX_RESULT, StartPowerSave) (void);
+    STDMETHOD_(HX_RESULT, EndPowerSave) (void);
+    STDMETHOD_(HXBOOL, IsInPowerSave) (void);
+    STDMETHOD_(HXBOOL, CanStartPowerSave) (void);
+    STDMETHOD_(ULONG32, GetWakeUpInterval) (void);
+    STDMETHOD_(ULONG32, SetWakeUpInterval) (ULONG32 /*IN*/ ulWakeUpInterval);
+#endif
 };
 
 CHXClientEngine* CreatePlatformClientEngine( void );
Index: src/HXClientCFuncs.cpp
===================================================================
RCS file: /cvsroot/player/hxclientkit/src/HXClientCFuncs.cpp,v
retrieving revision 1.26.2.6
diff -u -w -r1.26.2.6 HXClientCFuncs.cpp
--- src/HXClientCFuncs.cpp	11 Feb 2009 11:03:57 -0000	1.26.2.6
+++ src/HXClientCFuncs.cpp	17 Sep 2009 08:58:13 -0000
@@ -1105,3 +1105,112 @@
                                                                         pMaxTime) : false;
     return result;
 }
+
+//power save interface
+/*!
+  @function ClientEngineStartPowerSave
+  @result: true on success, false on failure
+  @abstract determin whether the engine could goes into power save mode
+     if data processing (decode/encode etc) could last for a period of time without engine interaction, it is possible to be success.
+*/
+bool ClientEngineStartPowerSave()
+{
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    HX_RESULT outResult = HXR_FAIL;
+    SPIHXClientEngine spIClientEngine;
+    if ( CHXClientEngine::GetEngine( spIClientEngine.AsInOutParam() ) )
+    {
+        CHXClientEngine* pCHXClientEngine = spIClientEngine.Ptr();
+        outResult = pCHXClientEngine->StartPowerSave();
+    }
+    
+    return outResult == HXR_OK ? true:false;
+#else
+    return false;
+#endif
+}
+bool ClientEngineEndPowerSave()
+{
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    HX_RESULT outResult = HXR_FAIL;
+    SPIHXClientEngine spIClientEngine;
+    if ( CHXClientEngine::GetEngine( spIClientEngine.AsInOutParam() ) )
+    {
+        CHXClientEngine* pCHXClientEngine = spIClientEngine.Ptr();
+        outResult = pCHXClientEngine->EndPowerSave();
+    }
+
+    return outResult == HXR_OK ? true:false;
+#else
+        return false;
+#endif
+}
+bool ClientEngineIsInPowerSave()
+{
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    HX_RESULT outResult = HXR_FAIL;
+    SPIHXClientEngine spIClientEngine;
+    if ( CHXClientEngine::GetEngine( spIClientEngine.AsInOutParam() ) )
+    {
+        CHXClientEngine* pCHXClientEngine = spIClientEngine.Ptr();
+        outResult = pCHXClientEngine->IsInPowerSave();
+    }
+
+    return outResult == HXR_OK ? true:false;
+#else
+        return false;
+#endif
+
+}
+bool ClientEngineCanPowerSave()
+{
+#if defined(HELIX_FEATURE_POWER_SAVE)
+HX_RESULT outResult = HXR_FAIL;
+SPIHXClientEngine spIClientEngine;
+if ( CHXClientEngine::GetEngine( spIClientEngine.AsInOutParam() ) )
+{
+    CHXClientEngine* pCHXClientEngine = spIClientEngine.Ptr();
+    outResult = pCHXClientEngine->CanStartPowerSave();
+}
+
+return outResult == HXR_OK ? true:false;
+#else
+    return false;
+#endif
+}
+UInt32 ClientEngineGetWakeUpInterval()
+{
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    UInt32 ulWakeUpInterval = -1;
+    SPIHXClientEngine spIClientEngine;
+    if ( CHXClientEngine::GetEngine( spIClientEngine.AsInOutParam() ) )
+    {
+        CHXClientEngine* pCHXClientEngine = spIClientEngine.Ptr();
+        ulWakeUpInterval = pCHXClientEngine->GetWakeUpInterval();
+    }
+
+    return ulWakeUpInterval;
+#else
+        return 0;
+#endif
+
+}
+UInt32 ClientEngineSetWakeUpInterval(UInt32 ulWakeUpInterval)
+{
+#if defined(HELIX_FEATURE_POWER_SAVE)
+    UInt32 retval = -1;
+    SPIHXClientEngine spIClientEngine;
+    if ( CHXClientEngine::GetEngine( spIClientEngine.AsInOutParam() ) )
+    {
+        CHXClientEngine* pCHXClientEngine = spIClientEngine.Ptr();
+        retval = pCHXClientEngine->SetWakeUpInterval(ulWakeUpInterval);
+    }
+
+    return retval;
+#else
+        return 0;
+#endif
+    
+}
+
+