/*************************************************************************/ /* File : VideoLoader.cpp */ /* */ /* Author : Leïla AIT KACI */ /* Last Modification : 28/05/03 */ /*************************************************************************/ #include "CKAll.h" #include "CKVideo.h" #include "CKVideoManager.h" CKObjectDeclaration* FillBehaviorVideoLoaderDecl (); CKERROR CreateVideoLoaderProto (CKBehaviorPrototype **); int VideoLoader (const CKBehaviorContext& BehContext); CKERROR VideoLoaderCB (const CKBehaviorContext& BehContext); ////////////////////////////////////////////////////////////////////// // Defines ////////////////////////////////////////////////////////////////////// #define BB_NAME "Video Loader" #define BB_DESC "Expose loading 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_LOAD, IN_UNLOAD }; enum BB_OUT { OUT_LOAD, OUT_UNLOAD, OUT_ERROR }; enum BB_LOC { }; enum BB_PIN { }; enum BB_POUT { POUT_STATE, POUT_ERROR }; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// CKObjectDeclaration *FillBehaviorVideoLoaderDecl() { 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(0x7b3e1eea,0x44be0a98)); od->SetCreationFunction(CreateVideoLoaderProto); return od; } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// CKERROR CreateVideoLoaderProto(CKBehaviorPrototype** pproto) { CKBehaviorPrototype *proto = CreateCKBehaviorPrototype(BB_NAME); if(!proto) return CKERR_OUTOFMEMORY; //--- Inputs declaration proto->DeclareInput("Load"); proto->DeclareInput("Unload"); //--- Outputs declaration proto->DeclareOutput("Loaded"); proto->DeclareOutput("Unloaded"); proto->DeclareOutput("Error"); //----- Input Parameters Declaration //--- Output Parameters Declaration proto->DeclareOutParameter("State", CKPGUID_VIDEOSTATE, "Unloaded"); proto->DeclareOutParameter("Error", CKPGUID_STRING); //---- Settings Declaration proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL); proto->SetBehaviorFlags((CK_BEHAVIOR_FLAGS)(CKBEHAVIOR_TARGETABLE)); proto->SetFunction(VideoLoader); proto->SetBehaviorCallbackFct(VideoLoaderCB, CKCB_BEHAVIORLOAD|CKCB_BEHAVIORATTACH, NULL); *pproto = proto; return CK_OK; } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// int VideoLoader(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_LOAD) ) { beh->ActivateInput(IN_LOAD, FALSE); switch ( State ) { //////////////////////// case CK_VIDEO_INVALID: { // If previous state is loading or unloading, it means the BB were // active previously to this call. It therefore means that we already // tried loading and it failed ! if ( (PreviousState == CK_VIDEO_LOADING) || (PreviousState == CK_VIDEO_UNLOADING) ) RETURN_IF_FAILED( video->GetLastError() ); // And, we can load the video RETURN_IF_FAILED( video->Load() ); beh->ActivateInput(IN_LOAD, TRUE); } break; //////////////////////// case CK_VIDEO_UNLOADING: { OUTPUT_IF_FAILED( CK_VIDEOERR_UNLOADING ); // If we were not previously loading or unloading, // It means the BB were not activated prior to this call, // so, we return an error as we can't unload while loading. if ( (PreviousState != CK_VIDEO_LOADING) && (PreviousState != CK_VIDEO_UNLOADING) ) { beh->SetOutputParameterValue(POUT_STATE, &PreviousState); return CKBR_OK; } else beh->ActivateInput(IN_LOAD, TRUE); } break; //////////////////////// case CK_VIDEO_LOADING: beh->ActivateInput(IN_LOAD, TRUE); break; //////////////////////// case CK_VIDEO_STOPPED: case CK_VIDEO_PLAYING: case CK_VIDEO_PAUSED: beh->SetOutputParameterValue(POUT_ERROR, "Success", 8); beh->ActivateOutput(OUT_LOAD); return CKBR_OK; } } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// else if ( beh->IsInputActive(IN_UNLOAD) ) { beh->ActivateInput(IN_UNLOAD, FALSE); switch ( State ) { //////////////////////// case CK_VIDEO_INVALID: beh->SetOutputParameterValue(POUT_ERROR, "Success", 8); beh->ActivateOutput(OUT_UNLOAD); return CKBR_OK; //////////////////////// case CK_VIDEO_UNLOADING: beh->ActivateInput(IN_UNLOAD, TRUE); break; //////////////////////// case CK_VIDEO_LOADING: { OUTPUT_IF_FAILED( CK_VIDEOERR_LOADING ); // If we were not previously loading or unloading, // It means the BB were not activated prior to this call, // so, we return an error as we can't unload while loading. if ( (PreviousState != CK_VIDEO_LOADING) && (PreviousState != CK_VIDEO_UNLOADING) ) { // As we assume the previous state cannot be loading or unloading // when exiting the BB, we need to reset it before to leave. beh->SetOutputParameterValue(POUT_STATE, &PreviousState); return CKBR_OK; } else beh->ActivateInput(IN_UNLOAD, TRUE); } break; //////////////////////// case CK_VIDEO_STOPPED: case CK_VIDEO_PLAYING: case CK_VIDEO_PAUSED: { // If previous state is loading or unloading, it means the BB were // active previously to this call. It therefore means that we already // tried unloading and it failed ! if ( (PreviousState == CK_VIDEO_LOADING) || (PreviousState == CK_VIDEO_UNLOADING) ) { // As we assume the previous state cannot be loading or unloading // when exiting the BB, we need to reset it before to leave. beh->SetOutputParameterValue(POUT_STATE, &PreviousState); RETURN_IF_FAILED( video->GetLastError() ); } // And we can unload the video RETURN_IF_FAILED( video->Unload() ); beh->ActivateInput(IN_UNLOAD, TRUE); } break; } } return CKBR_ACTIVATENEXTFRAME; } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// CKERROR VideoLoaderCB(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; }