/*************************************************************************/ /* 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; }