CR-Client: client/xfadeplayer

Nicholas Hart <[email protected]>
Newsgroups gmane.comp.multimedia.helix.devel
Message-ID <[email protected]>
I haven't done one of these submissions in a while, so if I messed 
anything up please let me know.  :)

Modified by: [email protected]
Date: 02/24/09
Project: N/A
Bug Number: N/A
Bug URL: N/A

Synopsis: initial commit for a helix component plugin that implements a 
player object which provides cross-fade and gap-less playback between 
audio tracks.

Overview: please see SOD document for details about this project: 
https://helixcommunity.org/viewcvs/helix-client/www/2009/devdocs/XFP-SOD-CrossFadePlayer.doc?limit_changes=100&revision=1.2&view=log
This is the initial checkin for this product.  It is not yet finished, 
but I want to get what I have written so far checked in to CVS for safety.

Files Added:
umakefil - makefile script
xfadeplayerlib - makefile script for static lib
xfadeplayerdll - makefile script for dll
xfadeplayerdll_win32.pcf - win32 specific makefile script additions
hxcrossfadeplayer.h - header for HXCrossFadePlayer class
hxcrossfadeplayer.cpp - source for HXCrossFadePlayer class
hxcrossfadeplugin.h - header for HXCrossFadePlugin class
hxcrossfadeplugin.cpp - source for HXCrossFadePlugin class
guids.cpp - source for guid symbols
pub/ihxcrossfadeplayer.h - interface and guids for IHXCrossFadePlayer
test/umakefil - makefile script for test application
test/win32.pcf - win32 specific makefile script additions
test/mac.pcf - mac specific makefile script additions
test/unix.pcf - unix specific makefile script additions
test/main.cpp - source for test program main
test/testengine.h - header for client engine loader class
test/testengine.cpp - source for client engine loader class
test/testplayer.h - header for test player class
test/testplayer.cpp - source for test player class


Files Modified:
hxclient_3_1_0_atlas.bif - added client_xfadeplayer and 
client_xfadeplayer_test targets

Image Size and Heap Use impact (Client -Only):
xfadeplayer.dll - 36,864 bytes
heap use not measured, but shouldn't be much larger than using two 
instances of IHXPlayer.

Platforms and Profiles Affected:
win32
mac - should build, not verified or tested
linux/unix - should build, not verified or tested

Distribution Libraries Affected:
N/A

Distribution library impact and planned action:
N/A

Platforms and Profiles Build Verified:
win32

Platforms and Profiles Functionality verified:
win32

Branch: HEAD and hxclient_3_1_0_atlas

Copyright assignment: I am a RealNetworks employee or contractor

QA Instructions:
build and run the client_xfadeplayer_test application.


Index: hxclient_3_1_0_atlas.bif
===================================================================
RCS file: /cvsroot/client/build/BIF/hxclient_3_1_0_atlas.bif,v
retrieving revision 1.86
diff -u -w -r1.86 hxclient_3_1_0_atlas.bif
--- hxclient_3_1_0_atlas.bif	13 Feb 2009 17:04:36 -0000	1.86
+++ hxclient_3_1_0_atlas.bif	25 Feb 2009 18:10:22 -0000
@@ -17984,5 +17984,35 @@
        </dependlist>
      </module>

+    <!-- CLIENT/XFADEPLAYER -->
+    <module id="client_xfadeplayer" group="client" 
name="client/xfadeplayer">
+      <source_dependlist>
+        common_include
+      </source_dependlist>
+      <dependlist>
+        common_container
+        common_runtime
+        common_util
+        common_system
+        common_dbgtool
+      </dependlist>
+    </module>
+
+    <!-- CLIENT/XFADEPLAYER/TEST -->
+    <module id="client_xfadeplayer_test" group="client" 
name="client/xfadeplayer/test">
+      <source_dependlist>
+        common_include
+      </source_dependlist>
+      <dependlist>
+        common_container
+        common_runtime
+        common_util
+        common_system
+        common_dbgtool
+        client_xfadeplayer
+      </dependlist>
+    </module>
+
+
    </targets>
  </build>

_______________________________________________
Helix-client-dev mailing list
[email protected]
http://lists.helixcommunity.org/mailman/listinfo/helix-client-dev
Umakefil (text/plain, 2.4 KB)
# 
# ***** BEGIN LICENSE BLOCK *****
# Source last modified: $Id: Umakefil,v 1.9 2007/07/06 21:58:11 jfinnecy Exp $
# 
# Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
# 
# The contents of this file, and the files included with this file,
# are subject to the current version of the RealNetworks Public
# Source License (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the current version of the RealNetworks Community
# Source License (the "RCSL") available at
# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
# will apply. You may also obtain the license terms directly from
# RealNetworks.  You may not use this file except in compliance with
# the RPSL or, if you have a valid RCSL with RealNetworks applicable
# to this file, the RCSL.  Please see the applicable RPSL or RCSL for
# the rights, obligations and limitations governing use of the
# contents of the file.
# 
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 (the
# "GPL") in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your version of
# this file only under the terms of the GPL, and not to allow others
# to use your version of this file under the terms of either the RPSL
# or RCSL, indicate your decision by deleting the provisions above
# and replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient may
# use your version of this file under the terms of any one of the
# RPSL, the RCSL or the GPL.
# 
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
# 
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
# 
# Technology Compatibility Kit Test Suite(s) Location:
#    http://www.helixcommunity.org/content/tck
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 

UmakefileVersion(2,2)

MultiTargetMake(["xfadeplayerlib", "xfadeplayerdll"])
xfadeplayerdll (text/plain, 3.3 KB)
# 
# ***** BEGIN LICENSE BLOCK *****
# Source last modified: $Id: Umakefil,v 1.9 2007/07/06 21:58:11 jfinnecy Exp $
# 
# Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
# 
# The contents of this file, and the files included with this file,
# are subject to the current version of the RealNetworks Public
# Source License (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the current version of the RealNetworks Community
# Source License (the "RCSL") available at
# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
# will apply. You may also obtain the license terms directly from
# RealNetworks.  You may not use this file except in compliance with
# the RPSL or, if you have a valid RCSL with RealNetworks applicable
# to this file, the RCSL.  Please see the applicable RPSL or RCSL for
# the rights, obligations and limitations governing use of the
# contents of the file.
# 
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 (the
# "GPL") in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your version of
# this file only under the terms of the GPL, and not to allow others
# to use your version of this file under the terms of either the RPSL
# or RCSL, indicate your decision by deleting the provisions above
# and replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient may
# use your version of this file under the terms of any one of the
# RPSL, the RCSL or the GPL.
# 
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
# 
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
# 
# Technology Compatibility Kit Test Suite(s) Location:
#    http://www.helixcommunity.org/content/tck
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 

UmakefileVersion(2,2)

project.AddSources("hxcrossfadeplugin.cpp",
                   "guids.cpp")

project.AddModuleIncludes("common/include",
                          "client/include")

project.AddModuleLibraries("common/dbgtool[debuglib]",
                           "common/container[contlib]",
                           "common/runtime[runtlib]",
                           "common/system[syslib]",
                           "common/util[utillib]",
                           "client/xfadeplayer[xfadeplayerlib]")

project.ExportFunction("RMACreateInstance",
                       "IUnknown** ppIUnknown",
                       "common/include",
                       "hxplugn.h")
project.ExportFunction("RMAShutdown",
                       "void",
                       "common/include",
                       "hxplugn.h")
project.ExportFunction("SetDLLAccessPath",
                       "const char* pszPath")
project.ExportFunction("CanUnload2",
                       "void")

DLLTarget("xfadeplayer")
xfadeplayerlib (text/plain, 2.7 KB)
# 
# ***** BEGIN LICENSE BLOCK *****
# Source last modified: $Id: Umakefil,v 1.9 2007/07/06 21:58:11 jfinnecy Exp $
# 
# Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
# 
# The contents of this file, and the files included with this file,
# are subject to the current version of the RealNetworks Public
# Source License (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the current version of the RealNetworks Community
# Source License (the "RCSL") available at
# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
# will apply. You may also obtain the license terms directly from
# RealNetworks.  You may not use this file except in compliance with
# the RPSL or, if you have a valid RCSL with RealNetworks applicable
# to this file, the RCSL.  Please see the applicable RPSL or RCSL for
# the rights, obligations and limitations governing use of the
# contents of the file.
# 
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 (the
# "GPL") in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your version of
# this file only under the terms of the GPL, and not to allow others
# to use your version of this file under the terms of either the RPSL
# or RCSL, indicate your decision by deleting the provisions above
# and replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient may
# use your version of this file under the terms of any one of the
# RPSL, the RCSL or the GPL.
# 
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
# 
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
# 
# Technology Compatibility Kit Test Suite(s) Location:
#    http://www.helixcommunity.org/content/tck
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 

UmakefileVersion(2,2)

project.AddSources("hxcrossfadeplayer.cpp")

project.AddModuleIncludes("common/include",
                          "client/include",
                          "common/dbgtool/pub",
                          "common/container/pub",
                          "common/runtime/pub",
                          "common/system/pub",
                          "common/util/pub")

LibraryTarget("xfadeplayerlib")
xfadeplayerdll_win32.pcf (text/plain, 2.4 KB)
# 
# ***** BEGIN LICENSE BLOCK *****
# Source last modified: $Id: Umakefil,v 1.9 2007/07/06 21:58:11 jfinnecy Exp $
# 
# Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
# 
# The contents of this file, and the files included with this file,
# are subject to the current version of the RealNetworks Public
# Source License (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the current version of the RealNetworks Community
# Source License (the "RCSL") available at
# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
# will apply. You may also obtain the license terms directly from
# RealNetworks.  You may not use this file except in compliance with
# the RPSL or, if you have a valid RCSL with RealNetworks applicable
# to this file, the RCSL.  Please see the applicable RPSL or RCSL for
# the rights, obligations and limitations governing use of the
# contents of the file.
# 
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 (the
# "GPL") in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your version of
# this file only under the terms of the GPL, and not to allow others
# to use your version of this file under the terms of either the RPSL
# or RCSL, indicate your decision by deleting the provisions above
# and replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient may
# use your version of this file under the terms of any one of the
# RPSL, the RCSL or the GPL.
# 
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
# 
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
# 
# Technology Compatibility Kit Test Suite(s) Location:
#    http://www.helixcommunity.org/content/tck
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 

project.AddIncludes("platform/win")

project.AddSystemLibraries("user32.lib",
                           "advapi32.lib")
hxcrossfadeplayer.h (text/plain, 24.8 KB)
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: hxplay.h,v 1.64.2.2 2008/01/10 02:51:23 cdunn Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

#ifndef _HXCROSSFADEPLAYER_
#define _HXCROSSFADEPLAYER_


#include "hxtypes.h"
#include "hxcom.h"
#include "ihxcrossfadeplayer.h"
#include "hxcore.h"
#include "hxerror.h"
#include "hxclsnk.h"
//#include "hxgroup.h"
//#include "hxccf.h"
#include "unkimp.h"
#include "hxslist.h"
#include "baseobj.h"
#include "ihxcontextuser.h"

class HXCrossFadePlayer : public CUnknownIMP
                        , public CHXBaseCountingObject
                        , public IHXCrossFadePlayer
                        , public IHXPlayer
                        , public IHXClientState
                        , public IHXErrorSinkControl
                        , public IHXClientStateAdviseSinkControl
                        , public IHXClientAdviseSink
                        , public IHXErrorSink
                        , public IHXClientStateAdviseSink
                        , public IHXContextUser
{
protected:
    HXCrossFadePlayer();
    virtual ~HXCrossFadePlayer();

public:

    /*
     *  IUnknown methods
     */
    DECLARE_UNKNOWN(HXCrossFadePlayer);

    /*
     * IHXPlayer methods
     */

    /************************************************************************
     *  Method:
     *          IHXPlayer::GetClientEngine
     *  Purpose:
     *          Get the interface to the client engine object of which the
     *          player is a part of.
     *
     */
    STDMETHOD(GetClientEngine)  (THIS_ REF(IHXClientEngine*) pEngine);

    /************************************************************************
     *  Method:
     *          IHXPlayer::IsDone
     *  Purpose:
     *          Ask the player if it is done with the current presentation
     *
     */
    STDMETHOD_(HXBOOL,IsDone)   (THIS);

    /************************************************************************
     *  Method:
     *          IHXPlayer::IsLive
     *  Purpose:
     *          Ask the player whether it contains the live source
     *
     */
    STDMETHOD_(HXBOOL,IsLive)   (THIS);

    /************************************************************************
     *  Method:
     *          IHXPlayer::GetCurrentPlayTime
     *  Purpose:
     *          Get the current time on the Player timeline
     *
     */
    STDMETHOD_(ULONG32,GetCurrentPlayTime)  (THIS);

    /************************************************************************
     *  Method:
     *          IHXPlayer::OpenURL
     *  Purpose:
     *          Tell the player to begin playback of all its sources.
     *
     */
    STDMETHOD(OpenURL)          (THIS_ const char* /*IN*/ pURL);

    /************************************************************************
     *  Method:
     *          IHXPlayer::Begin
     *  Purpose:
     *          Tell the player to begin playback of all its sources.
     *
     */
    STDMETHOD(Begin)            (THIS);

    /************************************************************************
     *  Method:
     *          IHXPlayer::Stop
     *  Purpose:
     *          Tell the player to stop playback of all its sources.
     *
     */
    STDMETHOD(Stop)             (THIS);

    /************************************************************************
     *  Method:
     *          IHXPlayer::Pause
     *  Purpose:
     *          Tell the player to pause playback of all its sources.
     *
     */
    STDMETHOD(Pause)            (THIS);

    /************************************************************************
     *  Method:
     *          IHXPlayer::Seek
     *  Purpose:
     *          Tell the player to seek in the playback timeline of all its 
     *          sources.
     *
     */
    STDMETHOD(Seek)             (THIS_ ULONG32 ulTime);

    /************************************************************************
     *  Method:
     *      IHXPlayer::GetSourceCount
     *  Purpose:
     *      Returns the current number of source instances supported by
     *      this player instance.
     */
    STDMETHOD_(UINT16, GetSourceCount)  (THIS);

    /************************************************************************
     *  Method:
     *      IHXPlayer::GetSource
     *  Purpose:
     *      Returns the Nth source instance supported by this player.
     */
    STDMETHOD(GetSource)        (THIS_
                                 UINT16         nIndex,
                                 REF(IUnknown*) pUnknown);

    /************************************************************************
     *  Method:
     *      IHXPlayer::SetClientContext
     *  Purpose:
     *      Called by the client to install itself as the provider of client
     *      services to the core. This is traditionally called by the top 
     *      level client application.
     */
    STDMETHOD(SetClientContext) (THIS_ IUnknown* pUnknown);

    /************************************************************************
     *  Method:
     *      IHXPlayer::GetClientContext
     *  Purpose:
     *      Called to get the client context for this player. This is
     *      set by the top level client application.
     */
    STDMETHOD(GetClientContext) (THIS_ REF(IUnknown*) pUnknown);

    /************************************************************************
     *  Method:
     *      IHXPlayer::AddAdviseSink
     *  Purpose:
     *      Call this method to add a client advise sink.
     *
     */
    STDMETHOD(AddAdviseSink)    (THIS_ IHXClientAdviseSink* pAdviseSink);

    /************************************************************************
     *  Method:
     *      IHXPlayer::RemoveAdviseSink
     *  Purpose:
     *      Call this method to remove a client advise sink.
     */
    STDMETHOD(RemoveAdviseSink) (THIS_ IHXClientAdviseSink* pAdviseSink);

    /*
     *  IHXCrossFadePlayer methods
     */
    /************************************************************************
     *  Method:
     *       IHXCrossFadePlayer::Create
     *  Purpose:
     *       Initialize the player (similar to IHXClientEngine::CreatePlayer)
     */
    STDMETHOD(Create)           (THIS_ 
                                 IUnknown* /*IN*/ pUnknown);

    /************************************************************************
     *  Method:
     *       IHXCrossFadePlayer::Close
     *  Purpose:
     *       Terminate the player (similar to IHXClientEngine::ClosePlayer)
     */
    STDMETHOD(Close)            (THIS);

    /************************************************************************
     *  Method:
     *       IHXCrossFadePlayer::SetNextURL
     *  Purpose:
     *       Set the URL of the next presentation.
     */
    STDMETHOD(SetNextURL)       (THIS_ const char* /*IN*/ pURL);

    /************************************************************************
     *  Method:
     *       IHXCrossFadePlayer::BeginNext
     *  Purpose:
     *       Immediately begin the next presentation, if set.  Does not
     *       Perform cross-fade.
     */
    STDMETHOD(BeginNext)        (THIS);

    /************************************************************************
     *  Method:
     *       IHXCrossFadePlayer::SetCrossFadeProperties
     *  Purpose:
     *       Set the URL of the next presentation.
     */
    STDMETHOD(SetCrossFadeProperties)   (THIS_
                                         UINT32 /*IN*/ uOverlapDuration,
                                         UINT32 /*IN*/ uFadeOutDuration,
                                         UINT32 /*IN*/ uFadeInDuration);

    /*
     *  IHXErrorSinkControl methods
     */

    /************************************************************************
     *	Method:
     *	    IHXErrorSinkControl::AddErrorSink
     *	Purpose:
     *	    Call this method to tell the sink controller to handle an error
     *	    sink.
     *
     *	    This method also allows you to set a range of severity levels which
     *	    you will receive reports for.
     *
     *      Note: You should specify an invalid range (Low = 1, High = 0 for
     *            example) if you don't want to receive any errors.
     *
     *	    The default severity range is HXLOG_EMERG to HXLOG_INFO (0-6).
     */
    STDMETHOD(AddErrorSink)         (THIS_
                                     IHXErrorSink*  pErrorSink,	
                                     const UINT8    unLowSeverity,
                                     const UINT8    unHighSeverity);

    /************************************************************************
     *	Method:
     *	    IHXErrorSinkControl::AddErrorSink
     *	Purpose:
     *	    Call this method to remove an error sink.
     */
    STDMETHOD(RemoveErrorSink)      (THIS_ IHXErrorSink* pErrorSink);

    /*
     *	IHXClientAdviseSink methods
     */

    /************************************************************************
     *	Method:
     *	    IHXClientAdviseSink::OnPosLength
     *	Purpose:
     *	    Called to advise the client that the position or length of the
     *	    current playback context has changed.
     */
    STDMETHOD(OnPosLength)		(THIS_
					UINT32	  ulPosition,
					UINT32	  ulLength);

    /************************************************************************
     *	Method:
     *	    IHXClientAdviseSink::OnPresentationOpened
     *	Purpose:
     *	    Called to advise the client a presentation has been opened.
     */
    STDMETHOD(OnPresentationOpened)	(THIS);

    /************************************************************************
     *	Method:
     *	    IHXClientAdviseSink::OnPresentationClosed
     *	Purpose:
     *	    Called to advise the client a presentation has been closed.
     */
    STDMETHOD(OnPresentationClosed)	(THIS);

    /************************************************************************
     *	Method:
     *	    IHXClientAdviseSink::OnStatisticsChanged
     *	Purpose:
     *	    Called to advise the client that the presentation statistics
     *	    have changed. 
     */
    STDMETHOD(OnStatisticsChanged)	(THIS);

    /************************************************************************
     *	Method:
     *	    IHXClientAdviseSink::OnPreSeek
     *	Purpose:
     *	    Called by client engine to inform the client that a seek is
     *	    about to occur. The render is informed the last time for the 
     *	    stream's time line before the seek, as well as the first new
     *	    time for the stream's time line after the seek will be completed.
     *
     */
    STDMETHOD(OnPreSeek)	(THIS_
				ULONG32		    ulOldTime,
				ULONG32		    ulNewTime);

    /************************************************************************
     *	Method:
     *	    IHXClientAdviseSink::OnPostSeek
     *	Purpose:
     *	    Called by client engine to inform the client that a seek has
     *	    just occurred. The render is informed the last time for the 
     *	    stream's time line before the seek, as well as the first new
     *	    time for the stream's time line after the seek.
     *
     */
    STDMETHOD(OnPostSeek)	(THIS_
				ULONG32		    ulOldTime,
				ULONG32		    ulNewTime);

    /************************************************************************
     *	Method:
     *	    IHXClientAdviseSink::OnStop
     *	Purpose:
     *	    Called by client engine to inform the client that a stop has
     *	    just occurred. 
     *
     */
    STDMETHOD(OnStop)		(THIS);

    /************************************************************************
     *	Method:
     *	    IHXClientAdviseSink::OnPause
     *	Purpose:
     *	    Called by client engine to inform the client that a pause has
     *	    just occurred. The render is informed the last time for the 
     *	    stream's time line before the pause.
     *
     */
    STDMETHOD(OnPause)		(THIS_
				ULONG32		    ulTime);

    /************************************************************************
     *	Method:
     *	    IHXClientAdviseSink::OnBegin
     *	Purpose:
     *	    Called by client engine to inform the client that a begin or
     *	    resume has just occurred. The render is informed the first time 
     *	    for the stream's time line after the resume.
     *
     */
    STDMETHOD(OnBegin)		(THIS_
				ULONG32		    ulTime);

    /************************************************************************
     *	Method:
     *	    IHXClientAdviseSink::OnBuffering
     *	Purpose:
     *	    Called by client engine to inform the client that buffering
     *	    of data is occuring. The render is informed of the reason for
     *	    the buffering (start-up of stream, seek has occurred, network
     *	    congestion, etc.), as well as percentage complete of the 
     *	    buffering process.
     *
     */
    STDMETHOD(OnBuffering)	(THIS_
				ULONG32		    ulFlags,
				UINT16		    unPercentComplete);

    /************************************************************************
     *	Method:
     *	    IHXClientAdviseSink::OnContacting
     *	Purpose:
     *	    Called by client engine to inform the client is contacting
     *	    hosts(s).
     *
     */
    STDMETHOD(OnContacting)	(THIS_
				 const char*	pHostName);

    /*
     *  IHXErrorSink methods
     */

    /************************************************************************
     *	Method:
     *	    IHXErrorSink::ErrorOccurred
     *	Purpose:
     *	    After you have registered your error sink with an
     *	    IHXErrorSinkControl (either in the server or player core) this
     *	    method will be called to report an error, event, or status message.
     *
     *	    The meaning of the arguments is exactly as described in
     *	    hxerror.h
     */
    STDMETHOD(ErrorOccurred)	(THIS_
				const UINT8	unSeverity,  
				const ULONG32	ulHXCode,
				const ULONG32	ulUserCode,
				const char*	pUserString,
				const char*	pMoreInfoURL);

    /*
     * IHXClientState methods
     */

    /************************************************************************
     *  Method:
     *      IHXClientState::SetConfig
     *  Purpose:
     *      Set config values to modify the behavior of the client engine.
     *      ("HaltInConnected", TRUE) : Halt in the CONNECTED state, do not
     *      automatically transition to the PREFETCHED state.
     *      ("RestartToPrefetched", TRUE) : At end of media, do not close the engine.
     *      Pause and seek to zero at end of media, so the client state is
     *      PREFETCHED with a current media time of zero, ready for playback.
     *
     *      Refer to EHXClientState and EHXClientStateSTatus for further information.
     */
    STDMETHOD(SetConfig)            (THIS_ IHXValues* pValues);

    /************************************************************************
     *  Method:
     *      IHXClientState::Resume
     *  Purpose:
     *      Resume player state transition
     *      Used when the "HaltInConnected" config value has been set to true in SetConfig,
     *      and the client has halted in the connected state. Resuming will transition
     *      the client from the CONNECTED to the PREFETCHED state.
     *      Refer to EHXClientState        for further information.
     */
    STDMETHOD(Resume)               (THIS);

    /************************************************************************
     *  Method:
     *      IHXClientEngine::GetState
     *  Purpose:
     *      Returns the current state of the player, as defined in EHXClientState
     */
    STDMETHOD_(UINT16, GetState)    (THIS);


    /*
     * IHXClientStateAdviseSink methods
     */

    /************************************************************************
     *  Method:
     *      IHXClientStateAdviseSink::OnStateChange
     *  Purpose:
     *      Called by client engine to inform the client that the state has changed.
     *      States are defined in the enum EHXClientState, defined in this file.
     */
    STDMETHOD(OnStateChange)        (THIS_
                                     UINT16 uOldState,
                                     UINT16 uNewState);

    /*
     * IHXClientStateAdviseSinkControl methods
     */

    /************************************************************************
     *  Method:
     *      IHXClientStateAdviseSinkControl::AddClientStateAdviseSink
     *  Purpose:
     */
    STDMETHOD(AddClientStateAdviseSink) (THIS_
                            IHXClientStateAdviseSink* pClientStateAdviseSink);

    /************************************************************************
     *  Method:
     *      IHXClientStateAdviseSinkControl::RemoveClientStateAdviseSink
     *  Purpose:
     */
    STDMETHOD(RemoveClientStateAdviseSink) (THIS_
                            IHXClientStateAdviseSink* pClientStateAdviseSink);

    /* 
     * IHXContextUser methods
     */
    /*!
     @function  RegisterContext
     @abstract  Support for automatic initialization.
     @param     pIContext [in] This component should use this context to retrieve required services and interfaces
     @result    The component should return HXR_OK if initialization is successful
    */
    STDMETHOD (RegisterContext)(THIS_ IUnknown* pIContext);

private:
    // SubPlayer class - encapsulates an instance of IHXPlayer and allows the
    // HXCrossFadePlayer to control from which presentation we receive and
    // handle our IHXClientAdviseSink and IHXErrorSink notifications
    class SubPlayer : public CUnknownIMP
                    , public IHXPlayer
                    , public IHXClientAdviseSink
                    , public IHXErrorSink
                    , public IHXClientStateAdviseSink
    {
    protected:
        SubPlayer();
        virtual ~SubPlayer();

    public:

        /*
        *  IUnknown methods
        */
        DECLARE_UNKNOWN(SubPlayer);

        /*
         * IHXPlayer methods
         */
        STDMETHOD(GetClientEngine)  (THIS_ REF(IHXClientEngine*) pEngine);
        STDMETHOD_(HXBOOL,IsDone)   (THIS);
        STDMETHOD_(HXBOOL,IsLive)   (THIS);
        STDMETHOD_(ULONG32,GetCurrentPlayTime)  (THIS);
        STDMETHOD(OpenURL)          (THIS_ const char* /*IN*/ pURL);
        STDMETHOD(Begin)            (THIS);
        STDMETHOD(Stop)             (THIS);
        STDMETHOD(Pause)            (THIS);
        STDMETHOD(Seek)             (THIS_ ULONG32 ulTime);
        STDMETHOD_(UINT16, GetSourceCount)  (THIS);
        STDMETHOD(GetSource)        (THIS_
                                    UINT16         nIndex,
                                    REF(IUnknown*) pUnknown);
        STDMETHOD(SetClientContext) (THIS_ IUnknown* pUnknown);
        STDMETHOD(GetClientContext) (THIS_ REF(IUnknown*) pUnknown);
        STDMETHOD(AddAdviseSink)    (THIS_ IHXClientAdviseSink* pAdviseSink);
        STDMETHOD(RemoveAdviseSink) (THIS_ IHXClientAdviseSink* pAdviseSink);

        /*
         *  IHXClientAdviseSink methods
         */
        STDMETHOD(OnPosLength)          (THIS_
                                         UINT32 ulPosition,
                                         UINT32 ulLength);
        STDMETHOD(OnPresentationOpened) (THIS);
        STDMETHOD(OnPresentationClosed) (THIS);
        STDMETHOD(OnStatisticsChanged)  (THIS);
        STDMETHOD(OnPreSeek)            (THIS_
                                         ULONG32    ulOldTime,
                                         ULONG32    ulNewTime);
        STDMETHOD(OnPostSeek)           (THIS_
                                         ULONG32    ulOldTime,
                                         ULONG32    ulNewTime);
        STDMETHOD(OnStop)               (THIS);
        STDMETHOD(OnPause)              (THIS_ ULONG32 ulTime);
        STDMETHOD(OnBegin)              (THIS_ ULONG32 ulTime);
        STDMETHOD(OnBuffering)          (THIS_
                                         ULONG32    ulFlags,
                                         UINT16     unPercentComplete);
        STDMETHOD(OnContacting)         (THIS_ const char* pHostName);

        /*
         *  IHXErrorSink methods
         */
        STDMETHOD(ErrorOccurred)        (THIS_
                                         const UINT8    unSeverity,  
                                         const ULONG32  ulHXCode,
                                         const ULONG32  ulUserCode,
                                         const char*    pUserString,
                                         const char*    pMoreInfoURL);

        /*
         * IHXClientStateAdviseSink methods
         */
        STDMETHOD(OnStateChange)        (THIS_
                                        UINT16 uOldState,
                                        UINT16 uNewState);

        // public helpers
        void        SetActive(HXCrossFadePlayer* pParent);
        HX_RESULT   Init(IHXClientEngine* pEngine);
        HX_RESULT   Terminate(IHXClientEngine* pEngine);
        HX_RESULT   DelegateQI(REFCLSID rclsid, void** ppUnknown);

    private:
        HXCrossFadePlayer*  m_pParent;
        IHXPlayer*          m_pPlayer;
    };

    // ErrorSinkInfo class - allows us to keep track of error sinks and which
    // levels of notifications they wish to receive (the SubPlayer listens for
    // ALL levels, so HXCrossFadePlayer must perform filtering for its sinks).
    class ErrorSinkInfo
    {
    public:
        ErrorSinkInfo(IHXErrorSink* pErrorSink, 
                      UINT8 unLowSeverity, 
                      UINT8 unHighSeverity);
        ~ErrorSinkInfo();

        void Notify(const UINT8    unSeverity,  
                    const ULONG32  ulHXCode,
                    const ULONG32  ulUserCode,
                    const char*    pUserString,
                    const char*    pMoreInfoURL);

        BOOL IsSameErrorSink(IHXErrorSink* pErrorSink) const 
        { 
            return pErrorSink == m_pErrorSink; 
        }

    private:
        IHXErrorSink*   m_pErrorSink;
        UINT8           m_unLowSeverity;
        UINT8           m_unHighSeverity;
    };

    // private helpers
    HX_RESULT   Init(IUnknown* pUnknown);
    HX_RESULT   SetupPlayer(REF(SubPlayer*) pPlayer);
    HX_RESULT   FreePlayer(REF(SubPlayer*) pPlayer);
    HX_RESULT   LoadClientEngine();
    HX_RESULT   DelegateQI(REFCLSID rclsid, void** ppUnknown);
    void        Terminate();
    void        BeginCrossFade();
    void        EndCrossFade();

    BOOL        IsCrossFadeActive() const
    {
        // these two will be non-NULL if we're doing a cross-fade
        return m_pCurrentPlayer && m_pPreviousPlayer;
    }

    // private data
    SubPlayer*          m_pCurrentPlayer;
    SubPlayer*          m_pNextPlayer;
    SubPlayer*          m_pPreviousPlayer;
    IHXClientEngine*    m_pClientEngine;
    UINT32              m_uOverlapDuration;
    UINT32              m_uFadeOutDuration;
    UINT32              m_uFadeInDuration;
    CHXSimpleList       m_errorSinkList;
    CHXSimpleList       m_clientAdviseSinkList;
    CHXSimpleList       m_clientStateAdviseSinkList;
    HXBOOL              m_userInitiatedStop;
};

#endif //_HXCROSSFADEPLAYER_
hxcrossfadeplugin.h (text/plain, 9.1 KB)
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: hxplay.h,v 1.64.2.2 2008/01/10 02:51:23 cdunn Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

#ifndef _HXCROSSFADEPLUGIN_
#define _HXCROSSFADEPLUGIN_


#include "hxplugn.h"
#include "unkimp.h"
#include "hxccf.h"
//#include "ihxcontextuser.h"


class HXCrossFadePlugin : public CUnknownIMP
                        , public IHXPlugin
                        , public IHXComponentPlugin
                        //, public IHXContextUser
                        //, public IHXCommonClassFactory
{
protected:
    HXCrossFadePlugin();
    ~HXCrossFadePlugin();

public:
    DECLARE_UNKNOWN(HXCrossFadePlugin);

    /*
     *  IHXPlugin methods
     */

    /************************************************************************
     *  Method:
     *      IHXPlugin::GetPluginInfo
     *  Purpose:
     *      Returns the basic information about this plugin. Including:
     *
     *      bMultipleLoad   Whether or not this plugin can be instantiated
     *                      multiple times. All File Formats must set
     *                      this value to TRUE.  The only other type of
     *                      plugin that can specify bMultipleLoad=TRUE is
     *                      a filesystem plugin.  Any plugin that sets
     *                      this flag to TRUE must not use global variables
     *                      of any type.
     *
     *                      Setting this flag to TRUE implies that you
     *                      accept that your plugin may be instantiated
     *                      multiple times (possibly in different
     *                      address spaces).  Plugins are instantiated
     *                      multiple times only in the server (for
     *                      performance reasons).
     *
     *                      An example of a plugin, that must set this
     *                      flag to FALSE is a filesystem plugin that 
     *                      uses a single TCP connection to communicate
     *                      with a database.
     *                                
     *      pDescription    which is used in about UIs (can be NULL)
     *      pCopyright      which is used in about UIs (can be NULL)
     *      pMoreInfoURL    which is used in about UIs (can be NULL)
     *      ulVersionNumber The version of this plugin.
     */
    STDMETHOD(GetPluginInfo)    (THIS_
                                 REF(HXBOOL)      /*OUT*/ bMultipleLoad,
                                 REF(const char*) /*OUT*/ pDescription,
                                 REF(const char*) /*OUT*/ pCopyright,
                                 REF(const char*) /*OUT*/ pMoreInfoURL,
                                 REF(ULONG32)     /*OUT*/ ulVersionNumber);

    /************************************************************************
     *        Method:
     *            IHXPlugin::InitPlugin
     *        Purpose:
     *            Initializes the plugin for use. This interface must always be
     *            called before any other method is called. This is primarily needed 
     *            so that the plugin can have access to the context for creation of
     *            IHXBuffers and IMalloc.
     */
    STDMETHOD(InitPlugin)       (THIS_
                                 IUnknown*  /*IN*/  pContext);


    /*
     *	IHXComponentPlugin methods
     */

    /************************************************************************
     *  Method:
     *      IHXComponentPlugin::GetNumberComponents
     *  Purpose:
     */
    STDMETHOD_(UINT32, GetNumComponents)(THIS);

    /************************************************************************
     *  Method:
     *      IHXComponentPlugin::GetPackageName
     *  Purpose:
     */
    STDMETHOD_(char const*, GetPackageName)(THIS) CONSTMETHOD;

    /************************************************************************
     *  Method:
     *      IHXComponentPlugin::GetComponentInfoAtIndex
     *  Purpose:
     */
    STDMETHOD(GetComponentInfoAtIndex) (THIS_
                                        UINT32          /*IN*/  nIndex,
                                        REF(IHXValues*) /*OUT*/ pInfo);

    /************************************************************************
     *  Method:
     *      IHXComponentPlugin::CreateComponentInstance
     *  Purpose:
     */
    STDMETHOD(CreateComponentInstance)(THIS_
                                       REFCLSID         /*IN*/  rclsid,
                                       REF(IUnknown*)   /*OUT*/ ppUnknown,
                                       IUnknown*        /*IN*/  pUnkOuter);

    /* 
     * IHXContextUser methods
     */
    /*!
     @function  RegisterContext
     @abstract  Support for automatic initialization.
     @param     pIContext [in] This component should use this context to retrieve required services and interfaces
     @result    The component should return HXR_OK if initialization is successful
    */
    //STDMETHOD (RegisterContext)(THIS_ IUnknown* pIContext);

#if 0
    /*
     *  IHXCommonClassFactory methods
     */

    /************************************************************************
     *  Method:
     *      IHXCommonClassFactory::CreateInstance
     *  Purpose:
     *      Creates instances of common objects supported by the system,
     *      like IHXBuffer, IHXPacket, IHXValues, etc.
     *
     *      This method is similar to Window's CoCreateInstance() in its 
     *      purpose, except that it only creates objects of a well known
     *      types.
     *
     *      NOTE: Aggregation is never used. Therefore and outer unknown is
     *      not passed to this function, and you do not need to code for this
     *      situation.
     */
    STDMETHOD(CreateInstance)   (THIS_
                                 REFCLSID   /*IN*/  rclsid,
                                 void**     /*OUT*/ ppUnknown);

    /************************************************************************
     *  Method:
     *      IHXController::CreateInstanceAggregatable
     *  Purpose:
     *      Creates instances of common objects that can be aggregated
     *      supported by the system, like IHXSiteWindowed
     *
     *      This method is similar to Window's CoCreateInstance() in its 
     *      purpose, except that it only creates objects of a well known
     *      types.
     *
     *      NOTE 1: Unlike CreateInstance, this method will create internal
     *      objects that support Aggregation.
     *
     *      NOTE 2: The output interface is always the non-delegating 
     *      IUnknown.
     */
    STDMETHOD(CreateInstanceAggregatable)
                                (THIS_
                                 REFCLSID       /*IN*/  rclsid,
                                 REF(IUnknown*) /*OUT*/ ppUnknown,
                                 IUnknown*      /*IN*/  pUnkOuter);
#endif

private:
    IHXCommonClassFactory*  m_pCCF;
};




#endif // _HXCROSSFADEPLUGIN_
guids.cpp (text/plain, 285 B)
#define INITGUID

#include "hxtypes.h"
#include "hxcom.h"
#include "ihxcrossfadeplayer.h"
#include "hxcore.h"
#include "hxerror.h"
#include "hxclsnk.h"
#include "hxplugn.h"
#include "hxccf.h"
#include "ihxcontextuser.h"
#include "ihxpckts.h"
#include "ihxfgbuf.h"
#include "hxengin.h"
hxcrossfadeplayer.cpp (text/plain, 45.9 KB)
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: hxplay.cpp,v 1.185.2.9 2008/07/04 02:05:53 qluo Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

#include "hxcrossfadeplayer.h"
#include "hxassert.h"

#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif


BEGIN_INTERFACE_LIST(HXCrossFadePlayer)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXCrossFadePlayer)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXPlayer)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXErrorSinkControl)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXClientState)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXClientAdviseSink)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXErrorSink)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXContextUser)
    INTERFACE_LIST_ENTRY_DELEGATE_BLIND(DelegateQI)
END_INTERFACE_LIST


HXCrossFadePlayer::HXCrossFadePlayer()
    : m_pClientEngine(NULL)
    , m_pCurrentPlayer(NULL)
    , m_pNextPlayer(NULL)
    , m_pPreviousPlayer(NULL)
    , m_uOverlapDuration(0)
    , m_uFadeOutDuration(0)
    , m_uFadeInDuration(0)
    , m_userInitiatedStop(FALSE)
{
}

HXCrossFadePlayer::~HXCrossFadePlayer()
{
    Terminate();
}

/*
 * IHXPlayer methods
 */

/************************************************************************
 *  Method:
 *          IHXPlayer::GetClientEngine
 *  Purpose:
 *          Get the interface to the client engine object of which the
 *          player is a part of.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::GetClientEngine(REF(IHXClientEngine*) pEngine)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCurrentPlayer)
    {
        result = m_pCurrentPlayer->GetClientEngine(pEngine);
    }
    return result;
}

/************************************************************************
 *  Method:
 *          IHXPlayer::IsDone
 *  Purpose:
 *          Ask the player if it is done with the current presentation
 *
 */
STDMETHODIMP_(HXBOOL)
HXCrossFadePlayer::IsDone()
{
    HXBOOL result = TRUE;
    if (m_pCurrentPlayer)
    {
        result = m_pCurrentPlayer->IsDone();
    }
    return result;
}

/************************************************************************
 *  Method:
 *          IHXPlayer::IsLive
 *  Purpose:
 *          Ask the player whether it contains the live source
 *
 */
STDMETHODIMP_(HXBOOL)
HXCrossFadePlayer::IsLive()
{
    HXBOOL result = FALSE;
    if (m_pCurrentPlayer)
    {
        result = m_pCurrentPlayer->IsLive();
    }
    return result;
}

/************************************************************************
 *  Method:
 *          IHXPlayer::GetCurrentPlayTime
 *  Purpose:
 *          Get the current time on the Player timeline
 *
 */
STDMETHODIMP_(ULONG32)
HXCrossFadePlayer::GetCurrentPlayTime()
{
    ULONG32 result = 0;
    if (m_pCurrentPlayer)
    {
        result = m_pCurrentPlayer->GetCurrentPlayTime();
    }
    return result;
}

/************************************************************************
 *  Method:
 *          IHXPlayer::OpenURL
 *  Purpose:
 *          Tell the player to begin playback of all its sources.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::OpenURL(const char* /*IN*/ pURL)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCurrentPlayer)
    {
        result = m_pCurrentPlayer->OpenURL(pURL);
    }
    return result;
}

/************************************************************************
 *  Method:
 *          IHXPlayer::Begin
 *  Purpose:
 *          Tell the player to begin playback of all its sources.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::Begin()
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCurrentPlayer)
    {
        m_userInitiatedStop = FALSE; // reset this
        result = m_pCurrentPlayer->Begin();
    }
    return result;
}

/************************************************************************
 *  Method:
 *          IHXPlayer::Stop
 *  Purpose:
 *          Tell the player to stop playback of all its sources.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::Stop()
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCurrentPlayer)
    {
        m_userInitiatedStop = TRUE; // don't transition to the next track
        result = m_pCurrentPlayer->Stop();
    }
    return result;
}

/************************************************************************
 *  Method:
 *          IHXPlayer::Pause
 *  Purpose:
 *          Tell the player to pause playback of all its sources.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::Pause()
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCurrentPlayer)
    {
        result = m_pCurrentPlayer->Pause();
    }
    return result;
}

/************************************************************************
 *  Method:
 *          IHXPlayer::Seek
 *  Purpose:
 *          Tell the player to seek in the playback timeline of all its 
 *          sources.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::Seek(ULONG32 ulTime)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCurrentPlayer)
    {
        result = m_pCurrentPlayer->Seek(ulTime);
    }
    return result;
}

/************************************************************************
 *  Method:
 *      IHXPlayer::GetSourceCount
 *  Purpose:
 *      Returns the current number of source instances supported by
 *      this player instance.
 */
STDMETHODIMP_(UINT16)
HXCrossFadePlayer::GetSourceCount()
{
    UINT16 result = 0;
    if (m_pCurrentPlayer)
    {
        result = m_pCurrentPlayer->GetSourceCount();
    }
    return result;
}

/************************************************************************
 *  Method:
 *      IHXPlayer::GetSource
 *  Purpose:
 *      Returns the Nth source instance supported by this player.
 */
STDMETHODIMP
HXCrossFadePlayer::GetSource(UINT16         nIndex,
                             REF(IUnknown*) pUnknown)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCurrentPlayer)
    {
        result = m_pCurrentPlayer->GetSource(nIndex, pUnknown);
    }
    return result;
}

/************************************************************************
 *  Method:
 *      IHXPlayer::SetClientContext
 *  Purpose:
 *      Called by the client to install itself as the provider of client
 *      services to the core. This is traditionally called by the top 
 *      level client application.
 */
STDMETHODIMP
HXCrossFadePlayer::SetClientContext(IUnknown* pUnknown)
{
    HX_RESULT result = HXR_OK;

    // XXXNH: workaround for RegisterContext() not receiving the client engine...
    if (!m_pClientEngine)
    {
        result = Init(pUnknown);
    }

    // set the client context for each player
    if (SUCCEEDED(result))
    {
        if (m_pCurrentPlayer)
        {
            result = m_pCurrentPlayer->SetClientContext(pUnknown);
            HX_ASSERT(SUCCEEDED(result));
        }
        if (m_pNextPlayer)
        {
            result = m_pNextPlayer->SetClientContext(pUnknown);
            HX_ASSERT(SUCCEEDED(result));
        }
        if (m_pPreviousPlayer)
        {
            result = m_pPreviousPlayer->SetClientContext(pUnknown);
            HX_ASSERT(SUCCEEDED(result));
        }
    }
    return result;
}

/************************************************************************
 *  Method:
 *      IHXPlayer::GetClientContext
 *  Purpose:
 *      Called to get the client context for this player. This is
 *      set by the top level client application.
 */
STDMETHODIMP
HXCrossFadePlayer::GetClientContext(REF(IUnknown*) pUnknown)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCurrentPlayer)
    {
        result = m_pCurrentPlayer->GetClientContext(pUnknown);
    }
    return result;
}

/************************************************************************
 *  Method:
 *      IHXPlayer::AddAdviseSink
 *  Purpose:
 *      Call this method to add a client advise sink.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::AddAdviseSink(IHXClientAdviseSink* pAdviseSink)
{ 
    HX_RESULT result = HXR_OUTOFMEMORY;
    LISTPOSITION pos = m_clientAdviseSinkList.AddTail((void*)pAdviseSink);
    if (pos)
    {
        pAdviseSink->AddRef();
        result = HXR_OK;
    }
    return result;
}

/************************************************************************
 *  Method:
 *      IHXPlayer::RemoveAdviseSink
 *  Purpose:
 *      Call this method to remove a client advise sink.
 */
STDMETHODIMP
HXCrossFadePlayer::RemoveAdviseSink(IHXClientAdviseSink* pAdviseSink)
{
    HX_RESULT result = HXR_INVALID_PARAMETER;
    LISTPOSITION pos = m_clientAdviseSinkList.Find((void*)pAdviseSink);
    if (pos)
    {
        m_clientAdviseSinkList.RemoveAt(pos);
        pAdviseSink->Release();
        result = HXR_OK;
    }
    return result;
}

/*
 *  IHXCrossFadePlayer methods
 */
/************************************************************************
*  Method:
*       IHXCrossFadePlayer::Create
*  Purpose:
*       Initialize the player (similar to IHXClientEngine::CreatePlayer)
*/
STDMETHODIMP
HXCrossFadePlayer::Create(IUnknown* /*IN*/ pUnknown)
{
    // XXXNH: remove this Create() function from the interface, since we
    // now use IHXContextUser to initialize ourselves
    HX_ASSERT(FALSE); 
    return HXR_NOTIMPL;//Init(pUnknown);
}

/************************************************************************
*  Method:
*       IHXCrossFadePlayer::Close
*  Purpose:
*       Terminate the player (similar to IHXClientEngine::ClosePlayer)
*/
STDMETHODIMP
HXCrossFadePlayer::Close()
{
    Terminate();
    return HXR_OK;
}

/************************************************************************
*  Method:
*       IHXCrossFadePlayer::SetNextURL
*  Purpose:
*       Set the URL of the next presentation.
*/
STDMETHODIMP
HXCrossFadePlayer::SetNextURL(const char* /*IN*/ pURL)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (!IsCrossFadeActive() && m_pNextPlayer)
    {
        result = m_pNextPlayer->OpenURL(pURL);
        if (SUCCEEDED(result))
        {
            m_pNextPlayer->Begin(); // start buffering
        }
    }
    return result;
}

/************************************************************************
*  Method:
*       IHXCrossFadePlayer::BeginNext
*  Purpose:
*       Immediately begin the next presentation, if set.  Does not
*       Perform cross-fade.
*/
STDMETHODIMP
HXCrossFadePlayer::BeginNext()
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (!IsCrossFadeActive() && m_pNextPlayer && m_pCurrentPlayer)
    {
        // deactivate and then stop our current player
        m_pPreviousPlayer = m_pCurrentPlayer;
        m_pPreviousPlayer->SetActive(NULL);

        // make the next player active
        m_pCurrentPlayer = m_pNextPlayer;
        m_pCurrentPlayer->SetActive(this);

        // while we're doing a cross fade we don't have a "next" player
        m_pNextPlayer = NULL;

        // begin the next track
        result = m_pCurrentPlayer->Begin();
    }
    return result;
}

/************************************************************************
*  Method:
*       IHXCrossFadePlayer::SetCrossFadeProperties
*  Purpose:
*       Set the URL of the next presentation.
*/
STDMETHODIMP
HXCrossFadePlayer::SetCrossFadeProperties(UINT32 /*IN*/ uOverlapDuration,
                                          UINT32 /*IN*/ uFadeOutDuration,
                                          UINT32 /*IN*/ uFadeInDuration)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (!IsCrossFadeActive())
    {
        m_uOverlapDuration = uOverlapDuration;
        m_uFadeOutDuration = uFadeOutDuration;
        m_uFadeInDuration = uFadeInDuration;
        result = HXR_OK;
    }
    return result;
}

/*
 *  IHXErrorSinkControl methods
 */

/************************************************************************
 *	Method:
 *	    IHXErrorSinkControl::AddErrorSink
 *	Purpose:
 *	    Call this method to tell the sink controller to handle an error
 *	    sink.
 *
 *	    This method also allows you to set a range of severity levels which
 *	    you will receive reports for.
 *
 *      Note: You should specify an invalid range (Low = 1, High = 0 for
 *            example) if you don't want to receive any errors.
 *
 *	    The default severity range is HXLOG_EMERG to HXLOG_INFO (0-6).
 */
STDMETHODIMP
HXCrossFadePlayer::AddErrorSink(IHXErrorSink*   pErrorSink,
                                const UINT8     unLowSeverity,
                                const UINT8     unHighSeverity)
{
    HX_RESULT result = HXR_OUTOFMEMORY;
    ErrorSinkInfo* pErrorSinkInfo = new ErrorSinkInfo(pErrorSink, 
                                                      unLowSeverity, 
                                                      unHighSeverity);
    if (pErrorSinkInfo)
    {
        LISTPOSITION pos = m_errorSinkList.AddTail((void*)pErrorSinkInfo);
        if (pos)
        {
            result = HXR_OK;
        }
    }
    return result;
}

/************************************************************************
 *	Method:
 *	    IHXErrorSinkControl::RemoveErrorSink
 *	Purpose:
 *	    Call this method to remove an error sink.
 */
STDMETHODIMP
HXCrossFadePlayer::RemoveErrorSink(IHXErrorSink* pErrorSink)
{
    HX_RESULT result = HXR_INVALID_PARAMETER;
    LISTPOSITION pos = m_errorSinkList.GetHeadPosition();
    LISTPOSITION posLast = pos;
    while (pos && FAILED(result))
    {
        ErrorSinkInfo* pErrorSinkInfo = (ErrorSinkInfo*)m_errorSinkList.GetNext(pos);
        if (pErrorSinkInfo->IsSameErrorSink(pErrorSink))
        {
            m_errorSinkList.RemoveAt(posLast);
            delete pErrorSinkInfo;
            result = HXR_OK;
        }
        posLast = pos;
    }
    return result;
}

/*
 *	IHXClientAdviseSink methods
 */

/************************************************************************
 *	Method:
 *	    IHXClientAdviseSink::OnPosLength
 *	Purpose:
 *	    Called to advise the client that the position or length of the
 *	    current playback context has changed.
 */
STDMETHODIMP
HXCrossFadePlayer::OnPosLength(UINT32 ulPosition,
                               UINT32 ulLength)
{
    LISTPOSITION pos = m_clientAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientAdviseSink* pClientAdviseSink = 
            (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
        pClientAdviseSink->OnPosLength(ulPosition, ulLength);
    }
    return HXR_OK;
}

/************************************************************************
 *	Method:
 *	    IHXClientAdviseSink::OnPresentationOpened
 *	Purpose:
 *	    Called to advise the client a presentation has been opened.
 */
STDMETHODIMP
HXCrossFadePlayer::OnPresentationOpened()
{
    LISTPOSITION pos = m_clientAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientAdviseSink* pClientAdviseSink = 
            (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
        pClientAdviseSink->OnPresentationOpened();
    }
    return HXR_OK;
}

/************************************************************************
 *	Method:
 *	    IHXClientAdviseSink::OnPresentationClosed
 *	Purpose:
 *	    Called to advise the client a presentation has been closed.
 */
STDMETHODIMP
HXCrossFadePlayer::OnPresentationClosed()
{
    LISTPOSITION pos = m_clientAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientAdviseSink* pClientAdviseSink = 
            (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
        pClientAdviseSink->OnPresentationClosed();
    }
    return HXR_OK;
}

/************************************************************************
 *	Method:
 *	    IHXClientAdviseSink::OnStatisticsChanged
 *	Purpose:
 *	    Called to advise the client that the presentation statistics
 *	    have changed. 
 */
STDMETHODIMP
HXCrossFadePlayer::OnStatisticsChanged()
{
    LISTPOSITION pos = m_clientAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientAdviseSink* pClientAdviseSink = 
            (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
        pClientAdviseSink->OnStatisticsChanged();
    }
    return HXR_OK;
}

/************************************************************************
 *	Method:
 *	    IHXClientAdviseSink::OnPreSeek
 *	Purpose:
 *	    Called by client engine to inform the client that a seek is
 *	    about to occur. The render is informed the last time for the 
 *	    stream's time line before the seek, as well as the first new
 *	    time for the stream's time line after the seek will be completed.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::OnPreSeek(ULONG32 ulOldTime,
                             ULONG32 ulNewTime)
{
    LISTPOSITION pos = m_clientAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientAdviseSink* pClientAdviseSink = 
            (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
        pClientAdviseSink->OnPreSeek(ulOldTime, ulNewTime);
    }
    return HXR_OK;
}

/************************************************************************
 *	Method:
 *	    IHXClientAdviseSink::OnPostSeek
 *	Purpose:
 *	    Called by client engine to inform the client that a seek has
 *	    just occurred. The render is informed the last time for the 
 *	    stream's time line before the seek, as well as the first new
 *	    time for the stream's time line after the seek.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::OnPostSeek(ULONG32 ulOldTime,
                              ULONG32 ulNewTime)
{
    LISTPOSITION pos = m_clientAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientAdviseSink* pClientAdviseSink = 
            (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
        pClientAdviseSink->OnPostSeek(ulOldTime, ulNewTime);
    }
    return HXR_OK;
}

/************************************************************************
 *	Method:
 *	    IHXClientAdviseSink::OnStop
 *	Purpose:
 *	    Called by client engine to inform the client that a stop has
 *	    just occurred. 
 *
 */
STDMETHODIMP
HXCrossFadePlayer::OnStop()
{
    if (m_pNextPlayer && !m_userInitiatedStop)
    {
        BeginNext();
    }
    else
    {
        LISTPOSITION pos = m_clientAdviseSinkList.GetHeadPosition();
        while (pos)
        {
            IHXClientAdviseSink* pClientAdviseSink = 
                (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
            pClientAdviseSink->OnStop();
        }
    }
    return HXR_OK;
}

/************************************************************************
 *	Method:
 *	    IHXClientAdviseSink::OnPause
 *	Purpose:
 *	    Called by client engine to inform the client that a pause has
 *	    just occurred. The render is informed the last time for the 
 *	    stream's time line before the pause.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::OnPause(ULONG32 ulTime)
{
    LISTPOSITION pos = m_clientAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientAdviseSink* pClientAdviseSink = 
            (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
        pClientAdviseSink->OnPause(ulTime);
    }
    return HXR_OK;
}

/************************************************************************
 *	Method:
 *	    IHXClientAdviseSink::OnBegin
 *	Purpose:
 *	    Called by client engine to inform the client that a begin or
 *	    resume has just occurred. The render is informed the first time 
 *	    for the stream's time line after the resume.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::OnBegin(ULONG32 ulTime)
{
    LISTPOSITION pos = m_clientAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientAdviseSink* pClientAdviseSink = 
            (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
        pClientAdviseSink->OnBegin(ulTime);
    }
    return HXR_OK;
}

/************************************************************************
 *	Method:
 *	    IHXClientAdviseSink::OnBuffering
 *	Purpose:
 *	    Called by client engine to inform the client that buffering
 *	    of data is occuring. The render is informed of the reason for
 *	    the buffering (start-up of stream, seek has occurred, network
 *	    congestion, etc.), as well as percentage complete of the 
 *	    buffering process.
 *
 */
STDMETHODIMP
HXCrossFadePlayer::OnBuffering(ULONG32  ulFlags,
                               UINT16   unPercentComplete)
{
    LISTPOSITION pos = m_clientAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientAdviseSink* pClientAdviseSink = 
            (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
        pClientAdviseSink->OnBuffering(ulFlags, unPercentComplete);
    }
    return HXR_OK;
}

/************************************************************************
 *	Method:
 *	    IHXClientAdviseSink::OnContacting
 *	Purpose:
 *	    Called by client engine to inform the client is contacting
 *	    hosts(s).
 *
 */
STDMETHODIMP
HXCrossFadePlayer::OnContacting(const char* pHostName)
{
    LISTPOSITION pos = m_clientAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientAdviseSink* pClientAdviseSink = 
            (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
        pClientAdviseSink->OnContacting(pHostName);
    }
    return HXR_OK;
}

/*
 *  IHXErrorSink methods
 */

/************************************************************************
 *	Method:
 *	    IHXErrorSink::ErrorOccurred
 *	Purpose:
 *	    After you have registered your error sink with an
 *	    IHXErrorSinkControl (either in the server or player core) this
 *	    method will be called to report an error, event, or status message.
 *
 *	    The meaning of the arguments is exactly as described in
 *	    hxerror.h
 */
STDMETHODIMP
HXCrossFadePlayer::ErrorOccurred(const UINT8    unSeverity,  
                                 const ULONG32  ulHXCode,
                                 const ULONG32  ulUserCode,
                                 const char*    pUserString,
                                 const char*    pMoreInfoURL)
{
    LISTPOSITION pos = m_errorSinkList.GetHeadPosition();
    while (pos)
    {
        ErrorSinkInfo* pErrorSinkInfo = 
            (ErrorSinkInfo*)m_errorSinkList.GetNext(pos);
        pErrorSinkInfo->Notify(unSeverity,
                               ulHXCode,
                               ulUserCode,
                               pUserString,
                               pMoreInfoURL);
    }
    return HXR_OK;
}

/*
    * IHXClientState methods
    */

/************************************************************************
 *  Method:
 *      IHXClientState::SetConfig
 *  Purpose:
 *      Set config values to modify the behavior of the client engine.
 *      ("HaltInConnected", TRUE) : Halt in the CONNECTED state, do not
 *      automatically transition to the PREFETCHED state.
 *      ("RestartToPrefetched", TRUE) : At end of media, do not close the engine.
 *      Pause and seek to zero at end of media, so the client state is
 *      PREFETCHED with a current media time of zero, ready for playback.
 *
 *      Refer to EHXClientState and EHXClientStateSTatus for further information.
 */
STDMETHODIMP
HXCrossFadePlayer::SetConfig(IHXValues* pValues)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCurrentPlayer)
    {
        IHXClientState* pClientState = NULL;
        result = m_pCurrentPlayer->QueryInterface(IID_IHXClientState, 
                                                  (void**)&pClientState);
        if (SUCCEEDED(result))
        {
            result = pClientState->SetConfig(pValues);
            HX_RELEASE(pClientState);

            // also set config on our other player
            if (m_pNextPlayer)
            {
                result = m_pNextPlayer->QueryInterface(IID_IHXClientState, 
                                                       (void**)&pClientState);
                if (SUCCEEDED(result))
                {
                    result = pClientState->SetConfig(pValues);
                    HX_RELEASE(pClientState);
                }
            }
            else if (m_pPreviousPlayer)
            {
                result = m_pPreviousPlayer->QueryInterface(IID_IHXClientState, 
                                                           (void**)&pClientState);
                if (SUCCEEDED(result))
                {
                    result = pClientState->SetConfig(pValues);
                    HX_RELEASE(pClientState);
                }
            }
        }
    }
    return result;
}

/************************************************************************
 *  Method:
 *      IHXClientState::Resume
 *  Purpose:
 *      Resume player state transition
 *      Used when the "HaltInConnected" config value has been set to true in SetConfig,
 *      and the client has halted in the connected state. Resuming will transition
 *      the client from the CONNECTED to the PREFETCHED state.
 *      Refer to EHXClientState        for further information.
 */
STDMETHODIMP
HXCrossFadePlayer::Resume()
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCurrentPlayer)
    {
        IHXClientState* pClientState = NULL;
        result = m_pCurrentPlayer->QueryInterface(IID_IHXClientState, 
                                                  (void**)&pClientState);
        if (SUCCEEDED(result))
        {
            result = pClientState->Resume();
            pClientState->Release();

            // XXXNH: presumably we don't want to Resume() the other player
        }
    }
    return result;
}

/************************************************************************
 *  Method:
 *      IHXClientEngine::GetState
 *  Purpose:
 *      Returns the current state of the player, as defined in EHXClientState
 */
STDMETHODIMP_(UINT16)
HXCrossFadePlayer::GetState()
{
    UINT16 state = 0;
    if (m_pCurrentPlayer)
    {
        IHXClientState* pClientState = NULL;
        HX_RESULT result = m_pCurrentPlayer->QueryInterface(IID_IHXClientState, (void**)&pClientState);
        if (SUCCEEDED(result))
        {
            state = pClientState->GetState();
            pClientState->Release();
        }
    }
    return state;
}

/*
 * IHXClientStateAdviseSinkControl methods
 */

/************************************************************************
 *  Method:
 *      IHXClientStateAdviseSinkControl::AddClientStateAdviseSink
 *  Purpose:
 */
STDMETHODIMP
HXCrossFadePlayer::AddClientStateAdviseSink(IHXClientStateAdviseSink* pClientStateAdviseSink)
{
    HX_RESULT result = HXR_OUTOFMEMORY;
    LISTPOSITION pos = m_clientStateAdviseSinkList.AddTail((void*)pClientStateAdviseSink);
    if (pos)
    {
        pClientStateAdviseSink->AddRef();
        result = HXR_OK;
    }
    return result;
}

/************************************************************************
 *  Method:
 *      IHXClientStateAdviseSinkControl::RemoveClientStateAdviseSink
 *  Purpose:
 */
STDMETHODIMP
HXCrossFadePlayer::RemoveClientStateAdviseSink(IHXClientStateAdviseSink* pClientStateAdviseSink)
{
    HX_RESULT result = HXR_INVALID_PARAMETER;
    LISTPOSITION pos = m_clientStateAdviseSinkList.Find((void*)pClientStateAdviseSink);
    if (pos)
    {
        m_clientStateAdviseSinkList.RemoveAt(pos);
        pClientStateAdviseSink->Release();
        result = HXR_OK;
    }
    return result;
}

/*
 * IHXClientStateAdviseSink methods
 */

/************************************************************************
 *  Method:
 *      IHXClientStateAdviseSink::OnStateChange
 *  Purpose:
 *      Called by client engine to inform the client that the state has changed.
 *      States are defined in the enum EHXClientState, defined in this file.
 */
STDMETHODIMP
HXCrossFadePlayer::OnStateChange(UINT16 uOldState,
                                 UINT16 uNewState)
{
    LISTPOSITION pos = m_clientStateAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientStateAdviseSink* pClientStateAdviseSink = 
            (IHXClientStateAdviseSink*)m_clientStateAdviseSinkList.GetNext(pos);
        pClientStateAdviseSink->OnStateChange(uOldState, uNewState);
    }
    return HXR_OK;
}

/* 
 * IHXContextUser methods
 */
/*!
 @function  RegisterContext
 @abstract  Support for automatic initialization.
 @param     pIContext [in] This component should use this context to retrieve required services and interfaces
 @result    The component should return HXR_OK if initialization is successful
*/
STDMETHODIMP
HXCrossFadePlayer::RegisterContext(IUnknown* pIContext)
{
    return Init(pIContext);
}

HX_RESULT
HXCrossFadePlayer::DelegateQI(REFCLSID rclsid, void** ppUnknown)
{
    HX_RESULT result = HXR_NOTIMPL;
    if (m_pCurrentPlayer)
    {
        result = m_pCurrentPlayer->DelegateQI(rclsid, ppUnknown);
    }
    return result;
}

HX_RESULT
HXCrossFadePlayer::Init(IUnknown* pUnknown)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (!m_pClientEngine)
    {
        if (pUnknown)
        {
            // set our engine
            result = pUnknown->QueryInterface(IID_IHXClientEngine,
                                              (void**)&m_pClientEngine);
            if (SUCCEEDED(result))
            {
                // setup the first player
                result = SetupPlayer(m_pCurrentPlayer);
                if (SUCCEEDED(result))
                {
                    // and the second
                    result = SetupPlayer(m_pNextPlayer);
                    if (SUCCEEDED(result))
                    {
                        // make the current player active so we get its events
                        m_pCurrentPlayer->SetActive(this);
                    }
                    else
                    {
                        // cleanup
                        FreePlayer(m_pCurrentPlayer);
                    }
                }

                // cleanup
                if (FAILED(result))
                {
                    HX_RELEASE(m_pClientEngine);
                }
            }
        }
        else
        {
            result = HXR_INVALID_PARAMETER;
        }
    }
    return result;
}

HX_RESULT
HXCrossFadePlayer::SetupPlayer(REF(SubPlayer*) pPlayer)
{
    HX_ASSERT(m_pClientEngine);
    HX_ASSERT(!pPlayer);
    HX_RESULT result = SubPlayer::CreateObject(&pPlayer);
    if (SUCCEEDED(result))
    {
        // we're responsible for the initial AddRef when using CreateObject()
        pPlayer->AddRef(); 

        result = pPlayer->Init(m_pClientEngine);
        if (FAILED(result))
        {
            HX_RELEASE(pPlayer);
        }
    }
    return result;
}

HX_RESULT
HXCrossFadePlayer::FreePlayer(REF(SubPlayer*) pPlayer)
{
    HX_ASSERT(m_pClientEngine);
    HX_ASSERT(pPlayer);
    HX_RESULT result = pPlayer->Terminate(m_pClientEngine);
    HX_ASSERT(SUCCEEDED(result));
    HX_RELEASE(pPlayer);
    return result;
}

HX_RESULT
HXCrossFadePlayer::LoadClientEngine()
{
    HX_RESULT result = HXR_NOTIMPL;

    IUnknown* pUnknown = NULL; // XXXNH: load client engine

    if (SUCCEEDED(result))
    {
        result = Init(pUnknown);
    }

    return result;
}

void
HXCrossFadePlayer::Terminate()
{
    // ideally our sinks should already be removed by the caller
    HX_ASSERT(m_errorSinkList.GetCount() == 0);
    LISTPOSITION pos = m_errorSinkList.GetHeadPosition();
    while (pos)
    {
        ErrorSinkInfo* pErrorSinkInfo = 
            (ErrorSinkInfo*)m_errorSinkList.GetNext(pos);
        delete pErrorSinkInfo;
    }

    HX_ASSERT(m_clientAdviseSinkList.GetCount() == 0);
    pos = m_clientAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientAdviseSink* pClientAdviseSink = 
            (IHXClientAdviseSink*)m_clientAdviseSinkList.GetNext(pos);
        pClientAdviseSink->Release();
    }

    HX_ASSERT(m_clientStateAdviseSinkList.GetCount() == 0);
    pos = m_clientStateAdviseSinkList.GetHeadPosition();
    while (pos)
    {
        IHXClientStateAdviseSink* pClientStateAdviseSink = 
            (IHXClientStateAdviseSink*)m_clientStateAdviseSinkList.GetNext(pos);
        pClientStateAdviseSink->Release();
    }

    // free our players
    if (m_pCurrentPlayer)
    {
        FreePlayer(m_pCurrentPlayer);
    }

    if (m_pNextPlayer)
    {
        FreePlayer(m_pNextPlayer);
    }

    if (m_pPreviousPlayer)
    {
        FreePlayer(m_pPreviousPlayer);
    }

    if (m_pClientEngine)
    {
        // free the client engine if we loaded it?
        HX_RELEASE(m_pClientEngine);
    }
}

void
HXCrossFadePlayer::BeginCrossFade()
{
    // our current player becomes the previous one
    m_pPreviousPlayer = m_pCurrentPlayer;
    // we stop listening to its sink notifications
    m_pPreviousPlayer->SetActive(NULL);

    // our new current player is the next one
    m_pCurrentPlayer = m_pNextPlayer;
    // start listening to its sink notifications
    m_pCurrentPlayer->SetActive(this);

    // until we finish the previous player we do not have a next track
    m_pNextPlayer = NULL;
}

void
HXCrossFadePlayer::EndCrossFade()
{
    // we're done with this track, we can now have a next track
    m_pNextPlayer = m_pPreviousPlayer;
    m_pPreviousPlayer = NULL;
}

HXCrossFadePlayer::SubPlayer::SubPlayer()
    : m_pParent(NULL)
    , m_pPlayer(NULL)
{
}

HXCrossFadePlayer::SubPlayer::~SubPlayer()
{
}

/*
 *  IUnknown methods
 */
BEGIN_INTERFACE_LIST(HXCrossFadePlayer::SubPlayer)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXClientAdviseSink)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXErrorSink)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXClientStateAdviseSink)
END_INTERFACE_LIST


/*
* IHXPlayer methods
*/
STDMETHODIMP
HXCrossFadePlayer::SubPlayer::GetClientEngine(REF(IHXClientEngine*) pEngine)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer)
    {
        result = m_pPlayer->GetClientEngine(pEngine);
    }
    return result;
}

STDMETHODIMP_(HXBOOL)
HXCrossFadePlayer::SubPlayer::IsDone()
{
    HXBOOL result = TRUE;
    if (m_pPlayer)
    {
        result = m_pPlayer->IsDone();
    }
    return result;
}

STDMETHODIMP_(HXBOOL)
HXCrossFadePlayer::SubPlayer::IsLive()
{
    HXBOOL result = FALSE;
    if (m_pPlayer)
    {
        result = m_pPlayer->IsLive();
    }
    return result;
}

STDMETHODIMP_(ULONG32)
HXCrossFadePlayer::SubPlayer::GetCurrentPlayTime()
{
    ULONG32 result = 0;
    if (m_pPlayer)
    {
        result = m_pPlayer->GetCurrentPlayTime();
    }
    return result;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OpenURL(const char* /*IN*/ pURL)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer)
    {
        result = m_pPlayer->OpenURL(pURL);
    }
    return result;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::Begin()
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer)
    {
        result = m_pPlayer->Begin();
    }
    return result;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::Stop()
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer)
    {
        result = m_pPlayer->Stop();
    }
    return result;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::Pause()
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer)
    {
        result = m_pPlayer->Pause();
    }
    return result;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::Seek(ULONG32 ulTime)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer)
    {
        result = m_pPlayer->Seek(ulTime);
    }
    return result;
}

STDMETHODIMP_(UINT16)
HXCrossFadePlayer::SubPlayer::GetSourceCount()
{
    UINT16 result = 0;
    if (m_pPlayer)
    {
        result = m_pPlayer->GetSourceCount();
    }
    return result;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::GetSource(UINT16         nIndex,
                                        REF(IUnknown*) pUnknown)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer)
    {
        result = m_pPlayer->GetSource(nIndex, pUnknown);
    }
    return result;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::SetClientContext(IUnknown* pUnknown)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer)
    {
        result = m_pPlayer->SetClientContext(pUnknown);
    }
    return result;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::GetClientContext(REF(IUnknown*) pUnknown)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer)
    {
        result = m_pPlayer->GetClientContext(pUnknown);
    }
    return result;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::AddAdviseSink(IHXClientAdviseSink* pAdviseSink)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer)
    {
        result = m_pPlayer->AddAdviseSink(pAdviseSink);
    }
    return result;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::RemoveAdviseSink(IHXClientAdviseSink* pAdviseSink)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer)
    {
        result = m_pPlayer->RemoveAdviseSink(pAdviseSink);
    }
    return result;
}

/*
 *  IHXClientAdviseSink methods
 */
STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnPosLength(UINT32 ulPosition,
                                          UINT32 ulLength)
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->OnPosLength(ulPosition, ulLength);
    }
    return HXR_OK;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnPresentationOpened()
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->OnPresentationOpened();
    }
    return HXR_OK;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnPresentationClosed()
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->OnPresentationClosed();
    }
    return HXR_OK;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnStatisticsChanged()
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->OnStatisticsChanged();
    }
    return HXR_OK;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnPreSeek(ULONG32    ulOldTime,
                                        ULONG32    ulNewTime)
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->OnPreSeek(ulOldTime, ulNewTime);
    }
    return HXR_OK;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnPostSeek(ULONG32    ulOldTime,
                                         ULONG32    ulNewTime)
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->OnPostSeek(ulOldTime, ulNewTime);
    }
    return HXR_OK;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnStop()
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->OnStop();
    }
    return HXR_OK;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnPause(ULONG32 ulTime)
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->OnPause(ulTime);
    }
    return HXR_OK;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnBegin(ULONG32 ulTime)
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->OnBegin(ulTime);
    }
    return HXR_OK;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnBuffering(ULONG32    ulFlags,
                                          UINT16     unPercentComplete)
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->OnBuffering(ulFlags, unPercentComplete);
    }
    else if (ulFlags == BUFFERING_START_UP && unPercentComplete >= 99)
    {
        // we're buffered, so stop and wait until its time to begin
        m_pPlayer->Pause();
    }
    return HXR_OK;
}

STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnContacting(const char* pHostName)
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->OnContacting(pHostName);
    }
    return HXR_OK;
}

/*
 *  IHXErrorSink methods
 */
STDMETHODIMP
HXCrossFadePlayer::SubPlayer::ErrorOccurred(const UINT8    unSeverity,
                                            const ULONG32  ulHXCode,
                                            const ULONG32  ulUserCode,
                                            const char*    pUserString,
                                            const char*    pMoreInfoURL)
{
    // only notify our parent if we're the active player
    if (m_pParent)
    {
        m_pParent->ErrorOccurred(unSeverity,
                                 ulHXCode,
                                 ulUserCode,
                                 pUserString,
                                 pMoreInfoURL);
    }
    return HXR_OK;
}

/*
 * IHXClientStateAdviseSink methods
 */
STDMETHODIMP
HXCrossFadePlayer::SubPlayer::OnStateChange(UINT16 uOldState, UINT16 uNewState)
{
    if (m_pParent)
    {
        m_pParent->OnStateChange(uOldState, uNewState);
    }
    return HXR_OK;
}


// public helpers
void
HXCrossFadePlayer::SubPlayer::SetActive(HXCrossFadePlayer* pParent)
{
    m_pParent = pParent;
}

HX_RESULT
HXCrossFadePlayer::SubPlayer::DelegateQI(REFCLSID rclsid, void** ppUnknown)
{
    HX_RESULT result = HXR_NOTIMPL;
    if (m_pPlayer)
    {
        result = m_pPlayer->QueryInterface(rclsid, ppUnknown);
    }
    return result;
}

HX_RESULT
HXCrossFadePlayer::SubPlayer::Init(IHXClientEngine* pEngine)
{
    HX_ASSERT(!m_pPlayer);
    HX_ASSERT(pEngine);
    HX_RESULT result = pEngine->CreatePlayer(m_pPlayer);
    if (SUCCEEDED(result))
    {
        result = m_pPlayer->AddAdviseSink(this);
        if (SUCCEEDED(result))
        {
            IHXErrorSinkControl* pErrorSinkControl = NULL;
            result = m_pPlayer->QueryInterface(IID_IHXErrorSinkControl,
                                               (void**)&pErrorSinkControl);
            if (SUCCEEDED(result))
            {
                result = pErrorSinkControl->AddErrorSink(this, 
                                                         HXLOG_EMERG, 
                                                         HXLOG_INFO);
                pErrorSinkControl->Release();

                IHXClientStateAdviseSinkControl* 
                    pClientStateAdviseSinkControl = NULL;
                result = m_pPlayer->QueryInterface(IID_IHXClientStateAdviseSinkControl,
                                                   (void**)&pClientStateAdviseSinkControl);
                if (SUCCEEDED(result))
                {
                    result = pClientStateAdviseSinkControl->AddClientStateAdviseSink(this);
                    pClientStateAdviseSinkControl->Release();
                }
            }

            // cleanup
            if (FAILED(result))
            {
                m_pPlayer->RemoveAdviseSink(this);
            }
        }
        // cleanup
        if (FAILED(result))
        {
            pEngine->ClosePlayer(m_pPlayer);
            m_pPlayer = NULL;
        }
    }
    return result;
}

HX_RESULT
HXCrossFadePlayer::SubPlayer::Terminate(IHXClientEngine* pEngine)
{
    HX_ASSERT(m_pPlayer);
    HX_ASSERT(pEngine);
    HX_RESULT result = m_pPlayer->RemoveAdviseSink(this);
    HX_ASSERT(SUCCEEDED(result));

    IHXErrorSinkControl* pErrorSinkControl = NULL;
    result = m_pPlayer->QueryInterface(IID_IHXErrorSinkControl,
                                       (void**)&pErrorSinkControl);
    if (SUCCEEDED(result))
    {
        result = pErrorSinkControl->RemoveErrorSink(this);
        pErrorSinkControl->Release();
        HX_ASSERT(SUCCEEDED(result));

        IHXClientStateAdviseSinkControl* 
            pClientStateAdviseSinkControl = NULL;
        result = m_pPlayer->QueryInterface(IID_IHXClientStateAdviseSinkControl,
                                            (void**)&pClientStateAdviseSinkControl);
        if (SUCCEEDED(result))
        {
            result = pClientStateAdviseSinkControl->RemoveClientStateAdviseSink(this);
            pClientStateAdviseSinkControl->Release();
            HX_ASSERT(SUCCEEDED(result));
        }
    }

    result = pEngine->ClosePlayer(m_pPlayer);
    m_pPlayer = NULL;
    HX_ASSERT(SUCCEEDED(result));

    return result;
}

HXCrossFadePlayer::ErrorSinkInfo::ErrorSinkInfo(IHXErrorSink* pErrorSink,
                                                UINT8 unLowSeverity,
                                                UINT8 unHighSeverity)
    : m_pErrorSink(pErrorSink)
    , m_unLowSeverity(unLowSeverity)
    , m_unHighSeverity(unHighSeverity)
{
    m_pErrorSink->AddRef();
}

HXCrossFadePlayer::ErrorSinkInfo::~ErrorSinkInfo()
{
    m_pErrorSink->Release();
}

void
HXCrossFadePlayer::ErrorSinkInfo::Notify(const UINT8    unSeverity,  
                                         const ULONG32  ulHXCode,
                                         const ULONG32  ulUserCode,
                                         const char*    pUserString,
                                         const char*    pMoreInfoURL)
{
    if (unSeverity >= m_unLowSeverity && unSeverity <= m_unHighSeverity)
    {
        m_pErrorSink->ErrorOccurred(unSeverity,
                                    ulHXCode,
                                    ulUserCode,
                                    pUserString,
                                    pMoreInfoURL);
    }
}
hxcrossfadeplugin.cpp (text/plain, 11.8 KB)
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: hxplay.cpp,v 1.185.2.9 2008/07/04 02:05:53 qluo Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

#include "hxcrossfadeplugin.h"
#include "hxcrossfadeplayer.h"
#include "hxver.h"
#include "xfadeplayer.ver"
#include "pckunpck.h" // for SetBufferPropertyCCF()

#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif

#include "dllpath.h"
ENABLE_DLLACCESS_PATHS(xfadeplayer);


BEGIN_INTERFACE_LIST(HXCrossFadePlugin)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXPlugin)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXComponentPlugin)//IHXCommonClassFactory)
//    INTERFACE_LIST_ENTRY_SIMPLE(IHXContextUser)
END_INTERFACE_LIST


HXCrossFadePlugin::HXCrossFadePlugin()
    : m_pCCF(NULL)
{
}

HXCrossFadePlugin::~HXCrossFadePlugin()
{
    HX_RELEASE(m_pCCF);
}

/*
 *  IHXPlugin methods
 */

/************************************************************************
 *  Method:
 *      IHXPlugin::GetPluginInfo
 *  Purpose:
 *      Returns the basic information about this plugin. Including:
 *
 *      bMultipleLoad   Whether or not this plugin can be instantiated
 *                      multiple times. All File Formats must set
 *                      this value to TRUE.  The only other type of
 *                      plugin that can specify bMultipleLoad=TRUE is
 *                      a filesystem plugin.  Any plugin that sets
 *                      this flag to TRUE must not use global variables
 *                      of any type.
 *
 *                      Setting this flag to TRUE implies that you
 *                      accept that your plugin may be instantiated
 *                      multiple times (possibly in different
 *                      address spaces).  Plugins are instantiated
 *                      multiple times only in the server (for
 *                      performance reasons).
 *
 *                      An example of a plugin, that must set this
 *                      flag to FALSE is a filesystem plugin that 
 *                      uses a single TCP connection to communicate
 *                      with a database.
 *                                
 *      pDescription    which is used in about UIs (can be NULL)
 *      pCopyright      which is used in about UIs (can be NULL)
 *      pMoreInfoURL    which is used in about UIs (can be NULL)
 *      ulVersionNumber The version of this plugin.
 */
STDMETHODIMP
HXCrossFadePlugin::GetPluginInfo(REF(HXBOOL)      /*OUT*/ bMultipleLoad,
                                 REF(const char*) /*OUT*/ pDescription,
                                 REF(const char*) /*OUT*/ pCopyright,
                                 REF(const char*) /*OUT*/ pMoreInfoURL,
                                 REF(ULONG32)     /*OUT*/ ulVersionNumber)
{
    bMultipleLoad = FALSE;
    pDescription = "Helix Cross-Fade Player Plug-in";
    pCopyright = HXVER_COPYRIGHT;
    pMoreInfoURL = HXVER_MOREINFO;
    ulVersionNumber = TARVER_ULONG32_VERSION;

    return HXR_OK;
}

/************************************************************************
 *  Method:
 *      IHXPlugin::InitPlugin
 *  Purpose:
 *      Initializes the plugin for use. This interface must always be
 *      called before any other method is called. This is primarily needed 
 *      so that the plugin can have access to the context for creation of
 *      IHXBuffers and IMalloc.
 */
STDMETHODIMP
HXCrossFadePlugin::InitPlugin(IUnknown*  /*IN*/  pContext)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (!m_pCCF)
    {
        if (pContext)
        {
            result = pContext->QueryInterface(IID_IHXCommonClassFactory,
                                              (void**)&m_pCCF);
            if (FAILED(result))
            {
                result = HXR_INVALID_PARAMETER; // expecting a CCF from our context!
            }
        }
        else
        {
            result = HXR_INVALID_PARAMETER;
        }
    }
    return result;
}

/*
 *	IHXComponentPlugin methods
 */

/************************************************************************
 *  Method:
 *      IHXComponentPlugin::GetNumberComponents
 *  Purpose:
 */
STDMETHODIMP_(UINT32)
HXCrossFadePlugin::GetNumComponents()
{
    return 1;
}

/************************************************************************
 *  Method:
 *      IHXComponentPlugin::GetPackageName
 *  Purpose:
 */
STDMETHODIMP_(char const*)
HXCrossFadePlugin::GetPackageName() CONSTMETHOD
{
    return "xfadeplayer";
}

/************************************************************************
 *  Method:
 *      IHXComponentPlugin::GetComponentInfoAtIndex
 *  Purpose:
 */
STDMETHODIMP
HXCrossFadePlugin::GetComponentInfoAtIndex(UINT32          /*IN*/  nIndex,
                                           REF(IHXValues*) /*OUT*/ pInfo)
{
    HX_RESULT result = HXR_UNEXPECTED;
   
    if (m_pCCF)
    {
        IUnknown* pUnknown = NULL;
        result = m_pCCF->CreateInstance(CLSID_IHXValues, (void**)&pUnknown);
        if (SUCCEEDED(result))
        {
            result = pUnknown->QueryInterface(IID_IHXValues, (void**)&pInfo);
            if (SUCCEEDED(result))
            {
                GUID guidTmp = CLSID_IHXCrossFadePlayer;
                BYTE* pTmp = (BYTE*)&guidTmp;
                result = SetBufferPropertyCCF(pInfo, 
                                              PLUGIN_COMPONENT_CLSID,
			                      pTmp, 
                                              sizeof(guidTmp), 
                                              m_pCCF);

                // cleanup
                if (FAILED(result))
                {
                    HX_RELEASE(pInfo);
                }
            }

            pUnknown->Release();
        }
    }

    return result;
}

/************************************************************************
 *  Method:
 *      IHXComponentPlugin::CreateComponentInstance
 *  Purpose:
 */
STDMETHODIMP
HXCrossFadePlugin::CreateComponentInstance(REFCLSID         /*IN*/  rclsid,
                                           REF(IUnknown*)   /*OUT*/ ppUnknown,
                                           IUnknown*        /*IN*/  pUnkOuter)
{
    HX_RESULT result = HXR_NOTIMPL;

    if (IsEqualIID(rclsid, CLSID_IHXCrossFadePlayer))
    {
        result = HXCrossFadePlayer::CreateInstance(&ppUnknown);
    }

    return result;
}

/* 
 * IHXContextUser methods
 */
/*!
 @function  RegisterContext
 @abstract  Support for automatic initialization.
 @param     pIContext [in] This component should use this context to retrieve required services and interfaces
 @result    The component should return HXR_OK if initialization is successful
*/
/*
STDMETHODIMP
HXCrossFadePlugin::RegisterContext(IUnknown* pIContext)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCCF)
    {
        if (pIContext)
        {
            result = pIContext->QueryInterface(IID_IHXCommonClassFactory,
                                               (void**)&m_pCCF);
            if (FAILED(result))
            {
                result = HXR_INVALID_PARAMETER; // expecting a CCF from our context!
            }
        }
        else
        {
            result = HXR_INVALID_PARAMETER;
        }
    }
    return result;
}
*/

#if 0
/*
 *  IHXCommonClassFactory methods
 */

/************************************************************************
 *  Method:
 *      IHXCommonClassFactory::CreateInstance
 *  Purpose:
 *      Creates instances of common objects supported by the system,
 *      like IHXBuffer, IHXPacket, IHXValues, etc.
 *
 *      This method is similar to Window's CoCreateInstance() in its 
 *      purpose, except that it only creates objects of a well known
 *      types.
 *
 *      NOTE: Aggregation is never used. Therefore and outer unknown is
 *      not passed to this function, and you do not need to code for this
 *      situation.
 */
STDMETHODIMP
HXCrossFadePlugin::CreateInstance(REFCLSID   /*IN*/  rclsid,
                                  void**     /*OUT*/ ppUnknown)
{
    HX_RESULT result = HXR_INVALID_PARAMETER;
    if (ppUnknown)
    {
        if (IsEqualIID(rclsid, CLSID_IHXCrossFadePlayer))
        {
            IUnknown* pCrossFadePlayer = NULL;
            result = HXCrossFadePlayer::CreateInstance(&pCrossFadePlayer);
            if (SUCCEEDED(result))
            {
                *ppUnknown = (void*)pCrossFadePlayer;
            }
        }
        else
        {
            result = HXR_NOTIMPL;
        }
    }
    return result;
}

/************************************************************************
 *  Method:
 *      IHXController::CreateInstanceAggregatable
 *  Purpose:
 *      Creates instances of common objects that can be aggregated
 *      supported by the system, like IHXSiteWindowed
 *
 *      This method is similar to Window's CoCreateInstance() in its 
 *      purpose, except that it only creates objects of a well known
 *      types.
 *
 *      NOTE 1: Unlike CreateInstance, this method will create internal
 *      objects that support Aggregation.
 *
 *      NOTE 2: The output interface is always the non-delegating 
 *      IUnknown.
 */
STDMETHODIMP
HXCrossFadePlugin::CreateInstanceAggregatable(
                                    REFCLSID       /*IN*/  rclsid,
                                    REF(IUnknown*) /*OUT*/ ppUnknown,
                                    IUnknown*      /*IN*/  pUnkOuter)
{
    return HXR_NOTIMPL;
}
#endif


STDAPI ENTRYPOINTCALLTYPE ENTRYPOINT(HXCreateInstance)(IUnknown** /*OUT*/ ppIUnknown)
{
    return HXCrossFadePlugin::CreateInstance(ppIUnknown);
}

STDAPI ENTRYPOINTCALLTYPE ENTRYPOINT(CanUnload2)(void)
{
    return ((CHXBaseCountingObject::ObjectsActive() > 0) ? HXR_FAIL : HXR_OK);
}

STDAPI ENTRYPOINTCALLTYPE ENTRYPOINT(HXShutdown)(void)
{
    return HXR_OK;
}
ihxcrossfadeplayer.h (text/plain, 5 KB)
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: hxgroup.h,v 1.5 2007/07/06 20:43:41 jfinnecy Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

#ifndef _IHXCROSSFADEPLAYER_
#define _IHXCROSSFADEPLAYER_


/****************************************************************************
 * 
 *  Interface:
 * 
 *  IHXCrossFadePlayer
 * 
 *  Purpose:
 *      Provide mechanism for an audio cross-fade between two presentations.
 * 
 *  IID_IHXCrossFadePlayer:
 * 
 *  {0FFD9635-52C4-46b3-B2A8-E781C31AD7CF}
 * 
 */
DEFINE_GUID(IID_IHXCrossFadePlayer, 0xffd9635, 0x52c4, 0x46b3, 0xb2, 0xa8, 
            0xe7, 0x81, 0xc3, 0x1a, 0xd7, 0xcf);

#define CLSID_IHXCrossFadePlayer    IID_IHXCrossFadePlayer

#undef  INTERFACE
#define INTERFACE   IHXCrossFadePlayer


// forward decls
_INTERFACE IHXClientEngine;


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

    /*
     *  IHXCrossFadePlayer methods
     */
    /************************************************************************
     *  Method:
     *       IHXCrossFadePlayer::Create
     *  Purpose:
     *       Initialize the player (similar to IHXClientEngine::CreatePlayer)
     */
    STDMETHOD(Create)           (THIS_ 
                                 IUnknown* /*IN*/ pUnknown) PURE;

    /************************************************************************
     *  Method:
     *       IHXCrossFadePlayer::Close
     *  Purpose:
     *       Terminate the player (similar to IHXClientEngine::ClosePlayer)
     */
    STDMETHOD(Close)            (THIS) PURE;

    /************************************************************************
     *  Method:
     *       IHXCrossFadePlayer::SetNextURL
     *  Purpose:
     *       Set the URL of the next presentation.
     */
    STDMETHOD(SetNextURL)       (THIS_
				 const char* /*IN*/ pURL) PURE;

    /************************************************************************
     *  Method:
     *       IHXCrossFadePlayer::BeginNext
     *  Purpose:
     *       Immediately begin the next presentation, if set.  Does not
     *       Perform cross-fade.
     */
    STDMETHOD(BeginNext)       (THIS) PURE;

    /************************************************************************
     *  Method:
     *       IHXCrossFadePlayer::SetCrossFadeProperties
     *  Purpose:
     *       Set the URL of the next presentation.
     */
    STDMETHOD(SetCrossFadeProperties)   (THIS_
				         UINT32 /*IN*/ uOverlapDuration,
                                         UINT32 /*IN*/ uFadeOutDuration,
                                         UINT32 /*IN*/ uFadeInDuration) PURE;

};

//#include "hxcomptr.h"
//DEFINE_SMART_PTR(IHXCrossFadePlayer)


#endif //_IHXCROSSFADEPLAYER_
Umakefil (text/plain, 2.9 KB)
# 
# ***** BEGIN LICENSE BLOCK *****
# Source last modified: $Id: Umakefil,v 1.9 2007/07/06 21:58:11 jfinnecy Exp $
# 
# Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
# 
# The contents of this file, and the files included with this file,
# are subject to the current version of the RealNetworks Public
# Source License (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the current version of the RealNetworks Community
# Source License (the "RCSL") available at
# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
# will apply. You may also obtain the license terms directly from
# RealNetworks.  You may not use this file except in compliance with
# the RPSL or, if you have a valid RCSL with RealNetworks applicable
# to this file, the RCSL.  Please see the applicable RPSL or RCSL for
# the rights, obligations and limitations governing use of the
# contents of the file.
# 
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 (the
# "GPL") in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your version of
# this file only under the terms of the GPL, and not to allow others
# to use your version of this file under the terms of either the RPSL
# or RCSL, indicate your decision by deleting the provisions above
# and replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient may
# use your version of this file under the terms of any one of the
# RPSL, the RCSL or the GPL.
# 
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
# 
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
# 
# Technology Compatibility Kit Test Suite(s) Location:
#    http://www.helixcommunity.org/content/tck
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 

UmakefileVersion(2,2)

project.AddSources("testplayer.cpp",
                   "testengine.cpp",
                   "main.cpp")

project.AddModuleIncludes("common/include",
                          "client/xfadeplayer/pub",
                          "client/include",
                          "common/fileio/pub")

project.AddModuleLibraries("common/container[contlib]",
                           "common/dbgtool[debuglib]",
                           "common/runtime[runtlib]",
                           "common/system[syslib]",
                           "common/util[utillib]")


ProgramTarget("xfadeplayertest")
mac.pcf (text/plain, 2.4 KB)
# 
# ***** BEGIN LICENSE BLOCK *****
# Source last modified: $Id: Umakefil,v 1.9 2007/07/06 21:58:11 jfinnecy Exp $
# 
# Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
# 
# The contents of this file, and the files included with this file,
# are subject to the current version of the RealNetworks Public
# Source License (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the current version of the RealNetworks Community
# Source License (the "RCSL") available at
# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
# will apply. You may also obtain the license terms directly from
# RealNetworks.  You may not use this file except in compliance with
# the RPSL or, if you have a valid RCSL with RealNetworks applicable
# to this file, the RCSL.  Please see the applicable RPSL or RCSL for
# the rights, obligations and limitations governing use of the
# contents of the file.
# 
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 (the
# "GPL") in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your version of
# this file only under the terms of the GPL, and not to allow others
# to use your version of this file under the terms of either the RPSL
# or RCSL, indicate your decision by deleting the provisions above
# and replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient may
# use your version of this file under the terms of any one of the
# RPSL, the RCSL or the GPL.
# 
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
# 
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
# 
# Technology Compatibility Kit Test Suite(s) Location:
#    http://www.helixcommunity.org/content/tck
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 

project.AddModuleIncludes("common/fileio/pub/platform/mac")
unix.pcf (text/plain, 2.4 KB)
# 
# ***** BEGIN LICENSE BLOCK *****
# Source last modified: $Id: Umakefil,v 1.9 2007/07/06 21:58:11 jfinnecy Exp $
# 
# Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
# 
# The contents of this file, and the files included with this file,
# are subject to the current version of the RealNetworks Public
# Source License (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the current version of the RealNetworks Community
# Source License (the "RCSL") available at
# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
# will apply. You may also obtain the license terms directly from
# RealNetworks.  You may not use this file except in compliance with
# the RPSL or, if you have a valid RCSL with RealNetworks applicable
# to this file, the RCSL.  Please see the applicable RPSL or RCSL for
# the rights, obligations and limitations governing use of the
# contents of the file.
# 
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 (the
# "GPL") in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your version of
# this file only under the terms of the GPL, and not to allow others
# to use your version of this file under the terms of either the RPSL
# or RCSL, indicate your decision by deleting the provisions above
# and replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient may
# use your version of this file under the terms of any one of the
# RPSL, the RCSL or the GPL.
# 
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
# 
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
# 
# Technology Compatibility Kit Test Suite(s) Location:
#    http://www.helixcommunity.org/content/tck
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 

project.AddModuleIncludes("common/fileio/pub/platform/unix")
win32.pcf (text/plain, 2.5 KB)
# 
# ***** BEGIN LICENSE BLOCK *****
# Source last modified: $Id: Umakefil,v 1.9 2007/07/06 21:58:11 jfinnecy Exp $
# 
# Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
# 
# The contents of this file, and the files included with this file,
# are subject to the current version of the RealNetworks Public
# Source License (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the current version of the RealNetworks Community
# Source License (the "RCSL") available at
# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
# will apply. You may also obtain the license terms directly from
# RealNetworks.  You may not use this file except in compliance with
# the RPSL or, if you have a valid RCSL with RealNetworks applicable
# to this file, the RCSL.  Please see the applicable RPSL or RCSL for
# the rights, obligations and limitations governing use of the
# contents of the file.
# 
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 (the
# "GPL") in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your version of
# this file only under the terms of the GPL, and not to allow others
# to use your version of this file under the terms of either the RPSL
# or RCSL, indicate your decision by deleting the provisions above
# and replace them with the notice and other provisions required by
# the GPL. If you do not delete the provisions above, a recipient may
# use your version of this file under the terms of any one of the
# RPSL, the RCSL or the GPL.
# 
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
# 
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
# 
# Technology Compatibility Kit Test Suite(s) Location:
#    http://www.helixcommunity.org/content/tck
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 

project.AddModuleIncludes("common/fileio/pub/platform/win")
project.AddSystemLibraries("advapi32.lib",
                           "user32.lib")
testengine.h (text/plain, 2.9 KB)
/* ***** BEGIN LICENSE BLOCK *****
 * Version: RCSL 1.0/RPSL 1.0
 *
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
 *
 * The contents of this file, and the files included with this file, are
 * subject to the current version of the RealNetworks Public Source License
 * Version 1.0 (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the RealNetworks Community Source License Version 1.0
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
 * in which case the RCSL will apply. You may also obtain the license terms
 * directly from RealNetworks.  You may not use this file except in
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
 * applicable to this file, the RCSL.  Please see the applicable RPSL or
 * RCSL for the rights, obligations and limitations governing use of the
 * contents of the file.
 *
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the portions
 * it created.
 *
 * This file, and the files included with this file, is distributed and made
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 *
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** */

#ifndef __testengine_h
#define __testengine_h

#include "hxtypes.h"
#include "hxcom.h"
#include "ihxmedpltfm.h"


// forward decls
_INTERFACE IHXClientEngine;
_INTERFACE IHXMediaPlatform;
_INTERFACE IHXCommonClassFactory;
_INTERFACE IHXMediaPlatformKicker;
class DLLAccess;


// a simple class to assist with loading and managing the Helix client engine
class TestEngine
{
public:
    TestEngine();
    virtual ~TestEngine();

    HX_RESULT   Load(const char* dllhome);
    HX_RESULT   Process();
    HX_RESULT   Close();

    IHXClientEngine*        GetClientEngineNoAddRef()       { return m_pEngine; }
    IHXCommonClassFactory*  GetCommonClassFactoryNoAddRef() { return m_pCCF; }

private:
    HX_RESULT   OpenEngine(const char* dllhome);
    void        DoEvent();

    DLLAccess*              m_pDLLAccess;
    IHXClientEngine*        m_pEngine;
    IHXMediaPlatform*       m_pMediaPlatform;
    IHXCommonClassFactory*  m_pCCF;
    IHXMediaPlatformKicker* m_pKicker;

    FPHXMEDIAPLATFORMOPEN   m_fpHXMediaPlatformOpen;
    FPHXCREATEMEDIAPLATFORM m_fpHXCreateMediaPlatform;
    FPHXMEDIAPLATFORMCLOSE  m_fpHXMediaPlatformClose;
/*
    FPRMCREATEENGINE        m_fpCreateEngine;
    FPRMCLOSEENGINE         m_fpCloseEngine;
    FPRMSETDLLACCESSPATH    m_fpSetDLLAccessPath;
    */
};

#endif // #ifndef __testengine_h
testplayer.h (text/plain, 3.9 KB)
/* ***** BEGIN LICENSE BLOCK *****
 * Version: RCSL 1.0/RPSL 1.0
 *
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
 *
 * The contents of this file, and the files included with this file, are
 * subject to the current version of the RealNetworks Public Source License
 * Version 1.0 (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the RealNetworks Community Source License Version 1.0
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
 * in which case the RCSL will apply. You may also obtain the license terms
 * directly from RealNetworks.  You may not use this file except in
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
 * applicable to this file, the RCSL.  Please see the applicable RPSL or
 * RCSL for the rights, obligations and limitations governing use of the
 * contents of the file.
 *
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the portions
 * it created.
 *
 * This file, and the files included with this file, is distributed and made
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 *
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** */

#ifndef __testplayer_h
#define __testplayer_h

#include "hxtypes.h"
#include "unkimp.h"
#include "hxcom.h"
#include "hxclsnk.h"
#include "hxerror.h"


// forward decls
_INTERFACE IHXPlayer;
_INTERFACE IHXCrossFadePlayer;
_INTERFACE IHXClientEngine;
_INTERFACE IHXCommonClassFactory;

class TestPlayer : public CUnknownIMP
                 , public IHXClientAdviseSink
                 , public IHXErrorSink
                 , public IHXClientStateAdviseSink
{
protected:
    TestPlayer();
    virtual ~TestPlayer();

public:
    DECLARE_UNKNOWN(TestPlayer);

    HX_RESULT   Init(IHXCommonClassFactory* pCCF, IHXClientEngine* pEngine);
    HX_RESULT   Terminate();
    HX_RESULT   CrossFadeURLs(const char* pURL1, 
                              const char* pURL2, 
                              UINT32 crossfadeDuration, 
                              UINT32 fadeOutDuration, 
                              UINT32 fadeInDuration);
    BOOL        IsPresentationClosed() const { return m_bPresentationClosed; }

    /*
     * IHXClientAdviseSink methods
     */
    STDMETHOD(OnPosLength)		(THIS_
					UINT32	  ulPosition,
					UINT32	  ulLength);
    STDMETHOD(OnPresentationOpened)	(THIS);
    STDMETHOD(OnPresentationClosed)	(THIS);
    STDMETHOD(OnStatisticsChanged)	(THIS);
    STDMETHOD(OnPreSeek)	(THIS_
				ULONG32		    ulOldTime,
				ULONG32		    ulNewTime);
    STDMETHOD(OnPostSeek)	(THIS_
				ULONG32		    ulOldTime,
				ULONG32		    ulNewTime);
    STDMETHOD(OnStop)		(THIS);
    STDMETHOD(OnPause)		(THIS_
				ULONG32		    ulTime);
    STDMETHOD(OnBegin)		(THIS_
				ULONG32		    ulTime);
    STDMETHOD(OnBuffering)	(THIS_
				ULONG32		    ulFlags,
				UINT16		    unPercentComplete);
    STDMETHOD(OnContacting)	(THIS_
				 const char*	pHostName);

    /*
     * IHXClientStateAdviseSink methods
     */
    STDMETHOD(OnStateChange)	(THIS_
				UINT16 uOldState,
				UINT16 uNewState
				);

    /*
     * IHXErrorSink methods
     */
    STDMETHOD(ErrorOccurred)	(THIS_
				const UINT8	unSeverity,  
				const ULONG32	ulHXCode,
				const ULONG32	ulUserCode,
				const char*	pUserString,
				const char*	pMoreInfoURL
				);

private:
    IHXPlayer*              m_pPlayer;
    IHXCrossFadePlayer*     m_pCrossFadePlayer;
    IHXClientEngine*        m_pEngine;
    IHXCommonClassFactory*  m_pCCF;
    HXBOOL                  m_bPresentationClosed;
};

#endif // #ifndef __testplayer_h
main.cpp (text/plain, 6.2 KB)
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: hxplay.cpp,v 1.185.2.9 2008/07/04 02:05:53 qluo Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

#define INITGUID
#include "hxtypes.h"
#include "testplayer.h"
#include "ihxcrossfadeplayer.h"
#include "hxcore.h"
#include "hxccf.h"
#include "ihxcontextuser.h"
#include "ihxmedpltfm.h"
#include "hxassert.h"
#include "hlxclib/stdlib.h"
#include "hxdir.h"
#include "hxstrutl.h"
#include "testengine.h"
#include "dllpath.h"

ENABLE_DLLACCESS_PATHS(_TestPlayer);


void Usage(const char* pProgPath)
{
    const char* pProgName = strstr(pProgPath, OS_SEPARATOR_STRING);
    if (!pProgName)
        pProgName = pProgPath;

    fprintf(stderr, "USAGE: %s [args] url1 url2\n", pProgName);
    fprintf(stderr, "optional arguments:\n");
    fprintf(stderr, "  --crossfade N    enable crossfade duration of N seconds\n");
    fprintf(stderr, "  --fadeout N      enable fade-out duration of N seconds\n");
    fprintf(stderr, "  --fadein N       enable fade-in duration of N seconds\n");
    fprintf(stderr, "  -h, --help       display usage information\n");
}


int main(int argc, char* argv[])
{
    const char* pURL1 = NULL;
    const char* pURL2 = NULL;
    UINT32 crossfadeDuration = 0;
    UINT32 fadeOutDuration = 0;
    UINT32 fadeInDuration = 0;

    // process command line args
    for (int i = 1; i < argc; ++i)
    {
        if (!strcasecmp(argv[i], "--crossfade") && i < argc-1)
        {
            ++i;
            crossfadeDuration = atoi(argv[i]);
        }
        else if (!strcasecmp(argv[i], "--fadeout") && i < argc-1)
        {
            ++i;
            fadeOutDuration = atoi(argv[i]);
        }
        else if (!strcasecmp(argv[i], "--fadein") && i < argc-1)
        {
            ++i;
            fadeInDuration = atoi(argv[i]);
        }
        else if (!strcasecmp(argv[i], "--help") ||
                 !strcasecmp(argv[i], "-h"))
        {
            Usage(argv[0]);
            return 0;
        }
        else if (argv[i][0] == '-')
        {
            fprintf(stderr, "invalid argument: %s\n", argv[i]);
            Usage(argv[0]);
            return 0;
        }
        else if (!pURL1)
        {
            pURL1 = argv[i];
        }
        else if (!pURL2)
        {
            pURL2 = argv[i];
        }
        else
        {
            fprintf(stderr, "extraneous argument: %s\n", argv[i]);
            Usage(argv[0]);
            return 0;
        }
    }

    // make sure we have two urls
    if (!pURL1 || !pURL2)
    {
        fprintf(stderr, "two URL arguments required\n");
        Usage(argv[0]);
        return 0;
    }

    // output our parsed parameters, for clarity
    fprintf(stderr, "crossfade duration: %d\n", crossfadeDuration);
    fprintf(stderr, "fade-out duration: %d\n", fadeOutDuration);
    fprintf(stderr, "fade-in duration: %d\n", fadeInDuration);
    fprintf(stderr, "first URL: %s\n", pURL1);
    fprintf(stderr, "second URL: %s\n", pURL2);

    TestEngine engine;
    HX_RESULT result = engine.Load("."); // try current dir
    if (SUCCEEDED(result))
    {
        // create our test player and run the test
        TestPlayer* pPlayer = NULL;
        HX_RESULT result = TestPlayer::CreateObject(&pPlayer);
        if (SUCCEEDED(result))
        {
            pPlayer->AddRef();
            result = pPlayer->Init(engine.GetCommonClassFactoryNoAddRef(),
                                   engine.GetClientEngineNoAddRef());
            if (SUCCEEDED(result))
            {
                // setup our URLs for playback
                result = pPlayer->CrossFadeURLs(pURL1, pURL2, crossfadeDuration, fadeOutDuration, fadeInDuration);

                // main loop
                while (SUCCEEDED(result) && !pPlayer->IsPresentationClosed())
                {
                    result = engine.Process();
                }
                result = pPlayer->Terminate();
                HX_ASSERT(SUCCEEDED(result));
            }
            pPlayer->Release();
        }
        result = engine.Close();
    }
    return 0;
}
testengine.cpp (text/plain, 9.6 KB)
/* ***** BEGIN LICENSE BLOCK *****
 * Version: RCSL 1.0/RPSL 1.0
 *
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
 *
 * The contents of this file, and the files included with this file, are
 * subject to the current version of the RealNetworks Public Source License
 * Version 1.0 (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the RealNetworks Community Source License Version 1.0
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
 * in which case the RCSL will apply. You may also obtain the license terms
 * directly from RealNetworks.  You may not use this file except in
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
 * applicable to this file, the RCSL.  Please see the applicable RPSL or
 * RCSL for the rights, obligations and limitations governing use of the
 * contents of the file.
 *
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the portions
 * it created.
 *
 * This file, and the files included with this file, is distributed and made
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 *
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** */


#include "testengine.h"
#include "hxassert.h"
#include "safestring.h"
#include "dllpath.h"
#include "dllacces.h"
#include "hxcom.h"
#include "hxcore.h"


TestEngine::TestEngine()
    : m_pDLLAccess(NULL)
    , m_pEngine(NULL)
    , m_pMediaPlatform(NULL)
    , m_pKicker(NULL)
    , m_fpHXMediaPlatformOpen(NULL)
    , m_fpHXCreateMediaPlatform(NULL)
    , m_fpHXMediaPlatformClose(NULL)
    /*
    , m_fpCreateEngine(NULL)
    , m_fpCloseEngine(NULL)
    , m_fpSetDLLAccessPath(NULL)
    */
{
}

TestEngine::~TestEngine()
{
}

HX_RESULT
TestEngine::OpenEngine(const char* dllhome)
{
    HX_RESULT result = HXR_OK;

    if (!m_pDLLAccess)
    {
        char staticLibPath[MAX_PATH];

        if (!dllhome)
        {
            result = HXR_INVALID_PARAMETER;
        }
        else
        {
#if defined (_STATICALLY_LINKED)
            // Load "clntcore" by default
            SafeSprintf(staticLibPath, MAX_PATH, "%s", "clntcore");
#else
#  if defined(_MAC_UNIX)
            SafeSprintf(staticLibPath, MAX_PATH, "%s/%s", dllhome, "hxmedpltfm.bundle");
#  elif defined(_UNIX)
            SafeSprintf(staticLibPath, MAX_PATH, "%s/%s", dllhome, "hxmedpltfm.so");
#  elif defined(_WINDOWS) || defined(_SYMBIAN)
            SafeSprintf(staticLibPath, MAX_PATH, "%s\\%s", dllhome, "hxmedpltfm.dll");
#  elif defined(_MACINTOSH)
#ifdef _MAC_MACHO
            SafeSprintf(staticLibPath, MAX_PATH, "clntcore.bundle");
#else
            if (strlen(dllhome) > 0 )
            {
                SafeSprintf(staticLibPath, MAX_PATH, "%s:%s", dllhome, "clntcore.shlb");
            }
            else
            {
                SafeSprintf(staticLibPath, MAX_PATH, "%s", "clntcore.shlb");
            }
#endif
#  endif
#endif

            GetDLLAccessPath()->SetPath(DLLTYPE_COMMON, dllhome);
            GetDLLAccessPath()->SetPath(DLLTYPE_PLUGIN, dllhome);
            GetDLLAccessPath()->SetPath(DLLTYPE_CODEC, dllhome);

            m_pDLLAccess = new DLLAccess();
            if (m_pDLLAccess)
            {
                int resultDLL = m_pDLLAccess->open(staticLibPath);
                switch (resultDLL)
                {
                    case DLLAccess::DLL_OK:
                    {
                        result = HXR_OK;
                    }
                    break;

                    case DLLAccess::NO_LOAD:
                    {
                        result = HXR_INVALID_PARAMETER; // bad path?
                    }
                    break;

                    case DLLAccess::OUT_OF_MEMORY:
                    {
                        result = HXR_OUTOFMEMORY;
                    }
                    break;

                    default:
                    {
                        result = HXR_FAIL; // probably a system error of some sort
                    }
                    break;
                }

                if (SUCCEEDED(result))
                {
                    m_fpHXMediaPlatformOpen = (FPHXMEDIAPLATFORMOPEN) m_pDLLAccess->getSymbol("HXMediaPlatformOpen");
                    m_fpHXCreateMediaPlatform = (FPHXCREATEMEDIAPLATFORM) m_pDLLAccess->getSymbol("HXCreateMediaPlatform");
                    m_fpHXMediaPlatformClose = (FPHXMEDIAPLATFORMCLOSE) m_pDLLAccess->getSymbol("HXMediaPlatformClose");
    /*
                    m_fpCreateEngine = (FPRMCREATEENGINE) m_pDLLAccess->getSymbol("CreateEngine");
                    m_fpCloseEngine  = (FPRMCLOSEENGINE)  m_pDLLAccess->getSymbol("CloseEngine");
                    m_fpSetDLLAccessPath = (FPRMSETDLLACCESSPATH) m_pDLLAccess->getSymbol("SetDLLAccessPath");
    */
                    if (m_fpHXMediaPlatformOpen == NULL ||
                        m_fpHXCreateMediaPlatform == NULL ||
                        m_fpHXMediaPlatformClose == NULL)/* ||
                        m_fpCreateEngine == NULL ||
                        m_fpCloseEngine == NULL ||
                        m_fpSetDLLAccessPath == NULL)*/
                    {
                        result = HXR_FAILED;
                    }
                }
            }
            else
            {
                result = HXR_OUTOFMEMORY;
            }
        }
    }

    return result;
}

HX_RESULT
TestEngine::Load(const char* dllhome)
{
    HX_RESULT result = OpenEngine(dllhome);
    if (SUCCEEDED(result))
    {
        result = m_fpHXMediaPlatformOpen();
        if (SUCCEEDED(result))
        {
            result = m_fpHXCreateMediaPlatform(&m_pMediaPlatform);
            if (SUCCEEDED(result))
            {
                result = m_pMediaPlatform->AddPluginPath("HelixSimplePlayer",
                                                         dllhome);
                if (SUCCEEDED(result))
                {
                    result = m_pMediaPlatform->Init(NULL);
                    if (SUCCEEDED(result))
                    {
                        result = m_pMediaPlatform->QueryInterface(
                                                    IID_IHXCommonClassFactory,
                                                    (void**)&m_pCCF);
                        if (SUCCEEDED(result))
                        {
                            result = m_pCCF->CreateInstance(
                                                    CLSID_IHXClientEngine, 
                                                    (void**)&m_pEngine);
                        }
                    }
                }
            }
        }

        if (FAILED(result))
        {
            Close();
        }
    }

    return result;
}

void
TestEngine::DoEvent()
{
#if defined(_WINDOWS)

    MSG msg;

    GetMessage(&msg, NULL, 0, 0);
    DispatchMessage(&msg);

#elif defined (_UNIX) && !defined(_MAC_UNIX)

    struct _HXxEvent* pNothing = 0;
    struct timeval    mtime;
    fd_set fds;
    int retval;
    
    UINT32 sleepTime = 0;
    
    //The new Atlas platform method.

    //Kick'ing the platforms gives time to all of its
    //schedulers. This is usefull for systems that do
    //not have threads enabled or do not have timers.
    if (m_pKicker)
    {
        m_pKicker->Kick(HXGetCurrentThreadID(), &sleepTime);
    }

    mtime.tv_sec  = 0;
    mtime.tv_usec = sleepTime;
    FD_ZERO(&fds);
    FD_SET(0, &fds);
    retval = select(1, &fds, NULL, NULL, &mtime);
    
#elif defined(__TCS__)
    _HXxEvent* pNothing = 0;

    // This is in units of 10ms.
    tmosTimSleep( 10 );
    if (m_pKicker)
    {
        pKicker->Kick(HXGetCurrentThreadID());
    }
    evtCount++;

    if (evtCount > 80)
    {
        evtFullCount++;
        if (evtFullCount > 10)
        {
            _alloc_stats(1);
            evtFullCount = 0;
        }
        else
        {
            _alloc_stats(0);
        }
        evtCount = 0;
    }

#elif defined (_MACINTOSH) || defined(_MAC_UNIX)

    EventRecord event;

    if (WaitNextEvent(everyEvent, &event, 1, nil))
    {
	switch (event.what)
	{
	    default:
            {
		HXxEvent _HXxEvent;
		_HXxEvent.event  = ((EventRecord*)&event)->what;
		_HXxEvent.param1 = &event;
		_HXxEvent.param2 = NULL; // IMPORTANT! Must be NULL or a RgnHandle!
		m_pEngine->EventOccurred(&_HXxEvent);
            }
            break;
	}
    }
    else
    {
	m_pEngine->EventOccurred(NULL);
    }
	
#elif defined(_SYMBIAN)
    // We have to allocate the object on the heap because
    // CActive does not appear to initialize iActive to 0
    // like it should
    // XXXNH: implement an event handler class to get this test program
    // working on Symbian...
    //SplayEventHandler* pEventHandler = new SplayEventHandler();
    //pEventHandler->DoEvents(20); // Process events for 20ms
    //delete pEventHandler;
#endif
}

HX_RESULT
TestEngine::Process()
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pEngine)
    {
        DoEvent();
        result = HXR_OK;
    }
    return result;
}

HX_RESULT
TestEngine::Close()
{
    HX_RESULT result = HXR_UNEXPECTED;

    if (m_pDLLAccess)
    {
        HX_RELEASE(m_pEngine);
        HX_RELEASE(m_pCCF);
        if (m_pMediaPlatform)
        {
            m_pMediaPlatform->Close();
            HX_RELEASE(m_pMediaPlatform);
        }
        HX_DELETE(m_pDLLAccess);
        result = HXR_OK;
    }

    return result;
}
testplayer.cpp (text/plain, 10.4 KB)
/* ***** BEGIN LICENSE BLOCK *****
 * Version: RCSL 1.0/RPSL 1.0
 *
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
 *
 * The contents of this file, and the files included with this file, are
 * subject to the current version of the RealNetworks Public Source License
 * Version 1.0 (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the RealNetworks Community Source License Version 1.0
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
 * in which case the RCSL will apply. You may also obtain the license terms
 * directly from RealNetworks.  You may not use this file except in
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
 * applicable to this file, the RCSL.  Please see the applicable RPSL or
 * RCSL for the rights, obligations and limitations governing use of the
 * contents of the file.
 *
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the portions
 * it created.
 *
 * This file, and the files included with this file, is distributed and made
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 *
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** */


#include "hxtypes.h"
#include "testplayer.h"
#include "ihxcrossfadeplayer.h"
#include "hxassert.h"
#include "hxcore.h"
#include "ihxcontextuser.h"
#include "hxccf.h"
#include "hlxclib/stdlib.h"


BEGIN_INTERFACE_LIST(TestPlayer)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXClientAdviseSink)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXErrorSink)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXClientStateAdviseSink)
END_INTERFACE_LIST


TestPlayer::TestPlayer()
    : m_pPlayer(NULL)
    , m_pCrossFadePlayer(NULL)
    , m_pEngine(NULL)
    , m_pCCF(NULL)
    , m_bPresentationClosed(FALSE)
{
}

TestPlayer::~TestPlayer()
{
}

HX_RESULT
TestPlayer::Init(IHXCommonClassFactory* pCCF, IHXClientEngine* pEngine)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (!m_pCCF && !m_pEngine && !m_pPlayer && !m_pCrossFadePlayer)
    {
        if (pCCF && pEngine)
        {
            m_pCCF = pCCF;
            m_pCCF->AddRef();
            m_pEngine = pEngine;
            m_pEngine->AddRef();

            // create our player
            IUnknown* pUnknown = NULL;
            result = m_pCCF->CreateInstance(CLSID_IHXCrossFadePlayer,
                                            (void**)&pUnknown);
            if (SUCCEEDED(result))
            {
                // get the IHXCrossFadePlayer interface
                result = pUnknown->QueryInterface(
                                            IID_IHXCrossFadePlayer,
                                            (void**)&m_pCrossFadePlayer);

                if (SUCCEEDED(result))
                {
                    // setup the player and give it our client engine
                    IHXContextUser* pContextUser = NULL;
                    result = pUnknown->QueryInterface(IID_IHXContextUser,
                                                      (void**)&pContextUser);
                    if (SUCCEEDED(result))
                    {
                        result = pContextUser->RegisterContext(m_pEngine);
                        pContextUser->Release();
                    }
                }

                if (SUCCEEDED(result))
                {
                    // get the IHXPlayer interface
                    result = pUnknown->QueryInterface(IID_IHXPlayer,
                                                    (void**)&m_pPlayer);
                    if (SUCCEEDED(result))
                    {
                        result = m_pPlayer->AddAdviseSink(this);
                    }

                    if (SUCCEEDED(result))
                    {
                        // add the error sink
                        IHXErrorSinkControl* pErrorSinkControl = NULL;
                        result = m_pPlayer->QueryInterface(
                                                    IID_IHXErrorSinkControl,
                                                    (void**)&pErrorSinkControl);
                        if (SUCCEEDED(result))
                        {
                            result = pErrorSinkControl->AddErrorSink(this, HXLOG_INFO, HXLOG_EMERG);
                            pErrorSinkControl->Release();
                        }
                    }

                    if (SUCCEEDED(result))
                    {
                        // add the state advise sink
                        IHXClientStateAdviseSinkControl*
                            pClientStateAdviseSinkControl = NULL;
                        result = m_pPlayer->QueryInterface(
                                        IID_IHXClientStateAdviseSinkControl,
                                        (void**)&pClientStateAdviseSinkControl);
                        if (SUCCEEDED(result))
                        {
                            result = pClientStateAdviseSinkControl->
                                AddClientStateAdviseSink(this);

                            pClientStateAdviseSinkControl->Release();
                        }
                    }
                }

                pUnknown->Release();
            }

            if (FAILED(result))
            {
                Terminate();
            }
        }
        else
        {
            result = HXR_INVALID_PARAMETER;
        }
    }
    return result;
}

HX_RESULT
TestPlayer::Terminate()
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pCCF || m_pEngine || m_pPlayer || m_pCrossFadePlayer)
    {
        if (m_pPlayer)
        {
            m_pPlayer->RemoveAdviseSink(this);

            // remove the error sink
            IHXErrorSinkControl* pErrorSinkControl = NULL;
            result = m_pPlayer->QueryInterface(
                                        IID_IHXErrorSinkControl,
                                        (void**)&pErrorSinkControl);
            if (SUCCEEDED(result))
            {
                result = pErrorSinkControl->RemoveErrorSink(this);
                pErrorSinkControl->Release();
            }

            // remove the state advise sink
            IHXClientStateAdviseSinkControl*
                pClientStateAdviseSinkControl = NULL;
            result = m_pPlayer->QueryInterface(
                                    IID_IHXClientStateAdviseSinkControl,
                                    (void**)&pClientStateAdviseSinkControl);
            if (SUCCEEDED(result))
            {
                result = pClientStateAdviseSinkControl->
                    RemoveClientStateAdviseSink(this);
                pClientStateAdviseSinkControl->Release();
            }

            HX_RELEASE(m_pPlayer);
        }

        if (m_pCrossFadePlayer)
        {
            m_pCrossFadePlayer->Close();
            HX_RELEASE(m_pCrossFadePlayer);
        }

        HX_RELEASE(m_pCCF);
        HX_RELEASE(m_pEngine);
    }
    return HXR_OK;
}

HX_RESULT
TestPlayer::CrossFadeURLs(const char* pURL1, 
                          const char* pURL2, 
                          UINT32 crossfadeDuration, 
                          UINT32 fadeOutDuration, 
                          UINT32 fadeInDuration)
{
    HX_RESULT result = HXR_UNEXPECTED;
    if (m_pPlayer && m_pCrossFadePlayer)
    {
        result = m_pPlayer->OpenURL(pURL1);
        if (SUCCEEDED(result))
        {
            result = m_pCrossFadePlayer->SetCrossFadeProperties(crossfadeDuration, fadeOutDuration, fadeInDuration);
            if (SUCCEEDED(result))
            {
                result = m_pCrossFadePlayer->SetNextURL(pURL2);
                if (SUCCEEDED(result))
                {
                    result = m_pPlayer->Begin();
                }
            }
        }
    }
    return result;
}

/*
 * IHXClientAdviseSink methods
 */
STDMETHODIMP
TestPlayer::OnPosLength(UINT32	  ulPosition,
                        UINT32	  ulLength)
{
    fprintf(stderr, "OnPosLength(%u, %u)\n", ulPosition, ulLength);
    return HXR_OK;
}

STDMETHODIMP
TestPlayer::OnPresentationOpened()
{
    fprintf(stderr, "OnPresentationOpened()\n");
    return HXR_OK;
}

STDMETHODIMP
TestPlayer::OnPresentationClosed()
{
    m_bPresentationClosed = TRUE;
    fprintf(stderr, "OnPresentationClosed()\n");
    return HXR_OK;
}

STDMETHODIMP
TestPlayer::OnStatisticsChanged()
{
    fprintf(stderr, "OnStatisticsChanged()\n");
    return HXR_OK;
}

STDMETHODIMP
TestPlayer::OnPreSeek(ULONG32		    ulOldTime,
                      ULONG32		    ulNewTime)
{
    fprintf(stderr, "OnPreSeek(%u, %u)\n", ulOldTime, ulNewTime);
    return HXR_OK;
}

STDMETHODIMP
TestPlayer::OnPostSeek(ULONG32		    ulOldTime,
                       ULONG32		    ulNewTime)
{
    fprintf(stderr, "OnPostSeek(%u, %u)\n", ulOldTime, ulNewTime);
    return HXR_OK;
}

STDMETHODIMP
TestPlayer::OnStop()
{
    fprintf(stderr, "OnStop()\n");
    return HXR_OK;
}

STDMETHODIMP
TestPlayer::OnPause(ULONG32		    ulTime)
{
    fprintf(stderr, "OnPause(%u)\n", ulTime);
    return HXR_OK;
}

STDMETHODIMP
TestPlayer::OnBegin(ULONG32		    ulTime)
{
    fprintf(stderr, "OnBegin(%u)\n", ulTime);
    return HXR_OK;
}

STDMETHODIMP
TestPlayer::OnBuffering(ULONG32		    ulFlags,
                        UINT16		    unPercentComplete)
{
    fprintf(stderr, "OnBuffering(%u, %u)\n", ulFlags, unPercentComplete);
    return HXR_OK;
}

STDMETHODIMP
TestPlayer::OnContacting(const char*	pHostName)
{
    fprintf(stderr, "OnContacting(\"%s\")\n", pHostName);
    return HXR_OK;
}

/*
 * IHXClientStateAdviseSink methods
 */
STDMETHODIMP
TestPlayer::OnStateChange(UINT16 uOldState,
                          UINT16 uNewState)
{
    fprintf(stderr, "OnStateChange(%u, %u)\n", uOldState, uNewState);
    return HXR_OK;
}

/*
 * IHXErrorSink methods
 */
STDMETHODIMP
TestPlayer::ErrorOccurred(const UINT8	unSeverity,
                          const ULONG32	ulHXCode,
                          const ULONG32	ulUserCode,
                          const char*	pUserString,
                          const char*	pMoreInfoURL)
{
    fprintf(stderr, "ErrorOccurred(%u, 0x%08x, 0x%08x, \"%s\", \"%s\")\n", unSeverity, ulHXCode, ulUserCode, pUserString ? pUserString : "", pMoreInfoURL ? pMoreInfoURL : "");
    return HXR_OK;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.