deargui-vpl/ref/virtools/Samples/Behaviors/Video/Sources/Video Player.cpp

371 lines
9.7 KiB
C++

/*************************************************************************/
/* File : VideoPlayer.cpp */
/* */
/* Author : Leïla AIT KACI */
/* Last Modification : 28/05/03 */
/*************************************************************************/
#include "CKAll.h"
#include "CKVideo.h"
#include "CKVideoManager.h"
CKObjectDeclaration* FillBehaviorVideoPlayerDecl ();
CKERROR CreateVideoPlayerProto (CKBehaviorPrototype **);
int VideoPlayer (const CKBehaviorContext& BehContext);
CKERROR VideoPlayerCB (const CKBehaviorContext& BehContext);
//////////////////////////////////////////////////////////////////////
// Defines
//////////////////////////////////////////////////////////////////////
#define BB_NAME "Video Player"
#define BB_DESC "Expose playing control on a video."
#define BB_CAT "Video/Basic"
#define BB_VERSION 0x00010000
#define BB_TARGET CKCID_VIDEO
#define RETURN_IF_FAILED(res) \
if ( res != CK_OK ) { \
XString err = video->GetErrorDescrition(res); \
beh->SetOutputParameterValue(POUT_ERROR, err.Str(), err.Length() + 1 ); \
beh->ActivateOutput(OUT_ERROR); \
return CKBR_OK; \
}
#define OUTPUT_IF_FAILED(res) \
if ( res != CK_OK ) { \
XString err = video->GetErrorDescrition(res); \
beh->SetOutputParameterValue(POUT_ERROR, err.Str(), err.Length() + 1 ); \
beh->ActivateOutput(OUT_ERROR); \
}
//////////////////////////////////////////////////////////////////////
// Enums for Parameter's Indexes
//////////////////////////////////////////////////////////////////////
enum BB_IN
{
IN_PLAY,
IN_STOP,
IN_PAUSE_RESUME
};
enum BB_OUT
{
OUT_PLAY,
OUT_STOP,
OUT_PAUSE,
OUT_RESUME,
OUT_ERROR
};
enum BB_LOC
{
SET_MANAGE_LOAD
};
enum BB_PIN
{
};
enum BB_POUT
{
POUT_STATE,
POUT_ERROR
};
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
CKObjectDeclaration *FillBehaviorVideoPlayerDecl()
{
CKObjectDeclaration *od = CreateCKObjectDeclaration(BB_NAME);
od->SetType(CKDLL_BEHAVIORPROTOTYPE);
od->SetCompatibleClassId(BB_TARGET);
od->SetDescription(BB_DESC);
od->SetVersion(BB_VERSION);
od->SetCategory(BB_CAT);
od->SetAuthorName("Virtools");
od->SetAuthorGuid(VIRTOOLS_GUID);
od->SetGuid(CKGUID(0xD854D4C8,0x40049375));
od->SetCreationFunction(CreateVideoPlayerProto);
return od;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
CKERROR CreateVideoPlayerProto(CKBehaviorPrototype** pproto)
{
CKBehaviorPrototype *proto = CreateCKBehaviorPrototype(BB_NAME);
if(!proto) return CKERR_OUTOFMEMORY;
//--- Inputs declaration
proto->DeclareInput("Play");
proto->DeclareInput("Stop");
proto->DeclareInput("Pause/Resume");
//--- Outputs declaration
proto->DeclareOutput("Start Playing");
proto->DeclareOutput("Stop Playing");
proto->DeclareOutput("Paused");
proto->DeclareOutput("Resumed");
proto->DeclareOutput("Error");
//----- Input Parameters Declaration
//--- Output Parameters Declaration
proto->DeclareOutParameter("State", CKPGUID_VIDEOSTATE, "Unloaded");
proto->DeclareOutParameter("Error", CKPGUID_STRING, "");
//---- Settings Declaration
proto->DeclareSetting("Manage Load / Unload", CKPGUID_BOOL, "TRUE");
proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL);
proto->SetBehaviorFlags((CK_BEHAVIOR_FLAGS)(CKBEHAVIOR_TARGETABLE));
proto->SetBehaviorCallbackFct(VideoPlayerCB, CKCB_BEHAVIORLOAD|CKCB_BEHAVIORATTACH, NULL);
proto->SetFunction(VideoPlayer);
*pproto = proto;
return CK_OK;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
int VideoPlayer(const CKBehaviorContext& BehContext)
{
CKContext* ctx = BehContext.Context;
CKBehavior* beh = BehContext.Behavior;
CKVideo* video = (CKVideo*) beh->GetTarget();
if ( !video ) {
XString err = "Invalid Video";
beh->SetOutputParameterValue(POUT_ERROR, err.Str(), err.Length() + 1 );
beh->ActivateOutput(OUT_ERROR);
return CKBR_OK;
}
// Get previous and current state
CK_VIDEO_STATE PreviousState;
CK_VIDEO_STATE State = video->GetState();
beh->GetOutputParameterValue(POUT_STATE, &PreviousState);
beh->SetOutputParameterValue(POUT_STATE, &State);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
if ( beh->IsInputActive(IN_PLAY) )
{
beh->ActivateInput(IN_PLAY, FALSE);
switch ( State )
{
////////////////////////
case CK_VIDEO_INVALID:
{
// we were loading, and we are now invalid, it means that
// the loading failed !
if ( PreviousState == CK_VIDEO_LOADING )
RETURN_IF_FAILED( video->GetLastError() );
// Should we manage loading or not.
CKBOOL iManageLoad;
beh->GetLocalParameterValue(SET_MANAGE_LOAD, &iManageLoad);
// First Load the video
if ( iManageLoad ) {
RETURN_IF_FAILED( video->Load() );
} else {
RETURN_IF_FAILED( CK_VIDEOERR_NOTLOADED );
}
// Reactivate input to come here again next frame
beh->ActivateInput(IN_PLAY, TRUE);
}
break;
////////////////////////
case CK_VIDEO_LOADING:
beh->ActivateInput(IN_PLAY, TRUE);
break;
////////////////////////
case CK_VIDEO_UNLOADING:
OUTPUT_IF_FAILED( CK_VIDEOERR_UNLOADING );
break;
////////////////////////
case CK_VIDEO_STOPPED:
case CK_VIDEO_PAUSED:
OUTPUT_IF_FAILED( video->Play() );
case CK_VIDEO_PLAYING:
beh->SetOutputParameterValue(POUT_ERROR, "Success", 8);
beh->ActivateOutput(OUT_PLAY);
break;
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
else if ( beh->IsInputActive(IN_STOP) )
{
beh->ActivateInput(IN_STOP, FALSE);
switch ( State )
{
////////////////////////
case CK_VIDEO_INVALID:
beh->SetOutputParameterValue(POUT_ERROR, "Success", 8);
beh->ActivateOutput(OUT_STOP);
return CKBR_OK;
////////////////////////
case CK_VIDEO_LOADING:
OUTPUT_IF_FAILED( CK_VIDEOERR_LOADING );
break;
////////////////////////
case CK_VIDEO_UNLOADING:
beh->ActivateInput(IN_STOP, TRUE);
break;
////////////////////////
case CK_VIDEO_PLAYING:
case CK_VIDEO_PAUSED:
{
CKERROR res = video->Stop();
if ( res != CK_OK ) {
OUTPUT_IF_FAILED( res );
break;
}
else
beh->ActivateInput(IN_STOP, TRUE);
}
break;
////////////////////////
case CK_VIDEO_STOPPED:
{
// we were unloading, and we are now stopped, it means that
// the unloading failed !
if ( PreviousState == CK_VIDEO_UNLOADING )
OUTPUT_IF_FAILED( CK_VIDEOERR_GENERIC );
// Otherwise, unload or activate stop output depending on
// Current setting.
CKBOOL ManageLoad;
beh->GetLocalParameterValue(SET_MANAGE_LOAD, &ManageLoad);
if ( ManageLoad ) {
CKERROR res = video->Unload();
if ( res == CK_OK )
beh->ActivateInput(IN_STOP, TRUE);
else {
OUTPUT_IF_FAILED( video->Unload() );
}
}
else {
beh->SetOutputParameterValue(POUT_ERROR, "Success", 8);
beh->ActivateOutput(OUT_STOP);
return CKBR_OK;
}
}
break;
return CKBR_ACTIVATENEXTFRAME;
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
else if ( beh->IsInputActive(IN_PAUSE_RESUME) )
{
beh->ActivateInput(IN_PAUSE_RESUME, FALSE);
switch ( State )
{
////////////////////////
case CK_VIDEO_INVALID:
RETURN_IF_FAILED(CK_VIDEOERR_NOTLOADED);
////////////////////////
case CK_VIDEO_LOADING:
OUTPUT_IF_FAILED(CK_VIDEOERR_LOADING);
break;
////////////////////////
case CK_VIDEO_UNLOADING:
OUTPUT_IF_FAILED(CK_VIDEOERR_UNLOADING);
break;
////////////////////////
case CK_VIDEO_STOPPED:
case CK_VIDEO_PAUSED:
{
CKERROR res = video->Play();
if ( res == CK_OK ) {
beh->SetOutputParameterValue(POUT_ERROR, "Success", 8);
beh->ActivateOutput(OUT_RESUME);
} else
OUTPUT_IF_FAILED( res );
}
break;
////////////////////////
case CK_VIDEO_PLAYING:
{
CKERROR res = video->Pause();
if ( res == CK_OK ) {
beh->SetOutputParameterValue(POUT_ERROR, "Success", 8);
beh->ActivateOutput(OUT_PAUSE);
} else
OUTPUT_IF_FAILED( res );
}
break;
}
return CKBR_ACTIVATENEXTFRAME;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
else
{
switch ( State )
{
// In case the video stops alone
case CK_VIDEO_STOPPED:
case CK_VIDEO_INVALID:
beh->ActivateInput(IN_STOP);
break;
}
}
return CKBR_ACTIVATENEXTFRAME;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
CKERROR VideoPlayerCB(const CKBehaviorContext& BehContext)
{
CKContext* ctx = BehContext.Context;
CKBehavior* beh = BehContext.Behavior;
switch (BehContext.CallbackMessage)
{
case CKM_BEHAVIORLOAD:
case CKM_BEHAVIORATTACH:
{
CK_VIDEO_STATE state = CK_VIDEO_INVALID;
beh->SetOutputParameterValue(POUT_STATE, &state);
}
break;
case CKM_BEHAVIORDELETE: break;
case CKM_BEHAVIORDETACH: break;
case CKM_BEHAVIORACTIVATESCRIPT: break;
case CKM_BEHAVIORDEACTIVATESCRIPT: break;
case CKM_BEHAVIORNEWSCENE: break;
default: return CKBR_OK;
}
return CKBR_OK;
}