#include "ordevicevideo_device.h"
#define FBX_CHANNEL_TAG "Channels"
#define FBX_VERSION_TAG "Version"
#define ORDEVICEVIDEO__CLASS ORDEVICEVIDEO__CLASSNAME
#define ORDEVICEVIDEO__NAME ORDEVICEVIDEO__CLASSSTR
#define ORDEVICEVIDEO__LABEL "OR - Video Device"
#define ORDEVICEVIDEO__DESC "OR - Video Manip/Switcher Device"
ORDEVICEVIDEO__CLASS,
ORDEVICEVIDEO__LABEL,
ORDEVICEVIDEO__DESC,
"object_video.png" );
static int gCount = 0;
bool ORDeviceVideo::FBCreate()
{
gCount++;
int lCnt = mSystem.Scene->Components.GetCount();
for(i=0;i<lCnt;i++)
{
FBComponent* lComponent = mSystem.Scene->Components[
i];
if( lComponent->Is( FBVideoSwitcher::TypeInfo ) )
{
FBVideoSwitcher* lVSwitch = (FBVideoSwitcher*)lComponent;
if( lVSwitch->IsSDKSwitcher() )
{
FBString lDevName = (const char*)lVSwitch->DeviceOwner->Name;
FBString lThisName = (
const char*)this->
Name;
if( lDevName == lThisName )
{
mVideoSwitcher = lVSwitch;
break;
}
}
}
}
if( !mVideoSwitcher )
{
char lBuffer[256];
sprintf( lBuffer, "Video Switcher (%d)", gCount );
mVideoSwitcher = new FBVideoSwitcher(lBuffer);
}
mVideoSwitcher->DeviceOwner = this;
mCurrentIndex = 0;
mModePlayback = kORPlaybackFreeRunning;
mVideoSwitcher->OnClipEnd.Add(
this, (
FBCallback) &ORDeviceVideo::VideoClipEndCallback );
return true;
}
void ORDeviceVideo::FBDestroy()
{
gCount--;
mVideoSwitcher->OnClipEnd.Remove(
this, (
FBCallback) &ORDeviceVideo::VideoClipEndCallback );
mVideoSwitcher->DeviceOwner =
NULL;
delete mVideoSwitcher;
}
unsigned long ORDeviceVideo::GetTotalFrames()
{
unsigned long lTotal=0;
for(i=0;i<mClips.GetCount();i++)
{
if(mClips[i]->GetVideo())
{
lTotal+= mClips[
i]->GetVideo()->LastFrame + 1;
}
}
return lTotal;
}
FBVideoClip* ORDeviceVideo::GetCurrentVideo()
{
if( mCurrentIndex < mClips.GetCount() && mCurrentIndex >= 0 )
{
return mClips[mCurrentIndex]->GetVideo();
}
}
int ORDeviceVideo::AddNewVideoClip()
{
return mClips.Add(
new ORVideoEntry(
NULL ) );
}
bool ORDeviceVideo::DeviceOperation( kDeviceOperations pOperation )
{
switch (pOperation)
{
case kOpInit: return Init();
case kOpStart: return Start();
case kOpStop: return Stop();
case kOpReset: return Reset();
case kOpDone: return Done();
}
return FBDevice::DeviceOperation( pOperation );
}
bool ORDeviceVideo::Init()
{
return true;
}
bool ORDeviceVideo::Start()
{
for( i=0; i<mClips.GetCount(); i++ )
{
if( !mClips[i]->GetVideo() )
{
FBMessageBox(
"Video Device Error",
"Some clips have not been assigned media",
"OK",
NULL,
NULL, 1 );
return false;
}
}
mCurrentIndex = 0;
mVideoSwitcher->ResetVideoSwitcher();
if( mClips.GetCount() > 0 )
{
}
return true;
}
bool ORDeviceVideo::Stop()
{
mCurrentIndex = 0;
return false;
}
bool ORDeviceVideo::Done()
{
return false;
}
bool ORDeviceVideo::Reset()
{
Stop();
return Start();
}
bool ORDeviceVideo::AnimationNodeNotify(FBAnimationNode* pAnimationNode ,FBEvaluateInfo* pEvaluateInfo)
{
double lFrame, lFrameLocal, lIndex;
mNodeFrame_IN ->ReadData ( &lFrame, pEvaluateInfo );
mNodeFrameLocal_IN ->ReadData ( &lFrameLocal, pEvaluateInfo );
mNodeIndex_IN ->ReadData ( &lIndex, pEvaluateInfo );
mNodeFrame_OUT ->WriteData( &lFrame, pEvaluateInfo );
mNodeFrameLocal_OUT ->WriteData( &lFrameLocal, pEvaluateInfo );
mNodeIndex_OUT ->WriteData( &lIndex, pEvaluateInfo );
return true;
}
bool ORDeviceVideo::DeviceEvaluationNotify(kTransportMode pMode, FBEvaluateInfo* pEvaluateInfo)
{
switch(pMode)
{
case kStop:
case kPlay:
{
if( mVideoSwitcher )
{
switch( mModePlayback )
{
case kORPlaybackFreeRunning:
{
mVideoSwitcher->PrepareNextFrame();
}
break;
case kORPlaybackGlobalFrame:
{
double lFrame;
mNodeFrame_IN->ReadData( &lFrame, pEvaluateInfo );
bool lFound = false;
int lCount=0,lNextCount=0;
int lFrameCnt;
lIntFrame = (
int) lFrame;
if( GetLoopMode() )
{
int lTotalFrame = GetTotalFrames();
if( lTotalFrame != 0 )
lIntFrame %= lTotalFrame;
}
lFrameCnt = mClips.GetCount();
for( i=0; i<lFrameCnt && !lFound; i++ )
{
lNextCount = lCount + mClips[
i]->GetVideo()->LastFrame + 1;
if( lIntFrame >= lCount && lIntFrame < lNextCount )
{
mVideoSwitcher->SwapCurrent( mClips[i]->GetVideo() );
mClips[
i]->GetVideo()->CurrentFrame = lIntFrame-lCount;
lFound = true;
}
lCount = lNextCount;
}
}
break;
case kORPlaybackLocalFrame:
{
double lFrame;
double lIndex;
mNodeIndex_IN->ReadData( &lIndex, pEvaluateInfo );
mNodeFrameLocal_IN ->ReadData( &lFrame, pEvaluateInfo );
int lClipCount = mClips.GetCount();
if( GetLoopMode() )
{
if( i<0 ) i = 0;
if( lClipCount != 0 ) i %= lClipCount;
}
else
{
if( i<0 ) i = 0;
if( i >= lClipCount ) i=lClipCount-1;
}
if( i >= 0 && i < lClipCount )
{
mVideoSwitcher->SwapCurrent( mClips[i]->GetVideo() );
mClips[
i]->GetVideo()->CurrentFrame = lFrame;
}
}
break;
}
}
AckOneSampleReceived();
}
break;
}
return true;
}
void ORDeviceVideo::DeviceIONotify( kDeviceIOs pAction,FBDeviceNotifyInfo &pDeviceNotifyInfo)
{
switch (pAction)
{
case kIOPlayModeWrite:
case kIOStopModeWrite:
{
}
break;
case kIOStopModeRead:
case kIOPlayModeRead:
{
}
break;
}
}
typedef FBArrayTemplate<FBVideoClip*> FBVideoArray;
static void GetVideoMediaList( FBVideoArray &pArray )
{
static FBSystem sSystem;
int z;
int lZMax = sSystem.Scene->VideoClips.GetCount();
for( z=0; z<lZMax; z++ )
{
pArray.Add( sSystem.Scene->VideoClips[z] );
}
}
#define FBX_CLIPLIST_TAG "Playlist"
bool ORDeviceVideo::FbxStore(FBFbxObject* pFbxObject,
kFbxObjectStore pStoreWhat)
{
{
pFbxObject->FieldWriteBegin( FBX_CLIPLIST_TAG );
{
pFbxObject->FieldWriteI( GetLoopMode() ? 1:0 );
pFbxObject->FieldWriteI( (int) GetPlaybackMode() );
FBVideoArray lVideoMedia;
GetVideoMediaList( lVideoMedia );
int lCnt = mClips.GetCount();
FBVideoClip* lVideo =
NULL;
int lIndex = -1;
pFbxObject->FieldWriteI( lCnt );
for( i=0; i<lCnt; i++ )
{
pFbxObject->FieldWriteC( mClips[i]->GetName() );
pFbxObject->FieldWriteI( mClips[i]->GetLoopCount() );
pFbxObject->FieldWriteI( mClips[i]->GetLoopsLeft() );
lVideo = mClips[
i]->GetVideo();
if( lVideo )
{
lIndex = lVideoMedia.Find( lVideo );
}
else
{
lIndex = -1;
}
pFbxObject->FieldWriteI( lIndex );
}
}
pFbxObject->FieldWriteEnd();
}
return true;
}
bool ORDeviceVideo::FbxRetrieve(FBFbxObject* pFbxObject,
kFbxObjectStore pStoreWhat)
{
if (pStoreWhat & kAttributes)
{
pFbxObject->FieldReadBegin( FBX_CLIPLIST_TAG );
{
SetLoopMode ( pFbxObject->FieldReadI() != 0 );
SetPlaybackMode ( (ORPlaybackMode) pFbxObject->FieldReadI() );
FBVideoArray lVideoMedia;
GetVideoMediaList( lVideoMedia );
int lCnt = pFbxObject->FieldReadI();
int lVideoIx, lClipIx;
int lLoopCnt, lLoopLeft;
FBString lName;
for( i=0; i<lCnt; i++ )
{
lName = pFbxObject->FieldReadC();
lLoopCnt = pFbxObject->FieldReadI();
lLoopLeft = pFbxObject->FieldReadI();
lVideoIx = pFbxObject->FieldReadI();
lClipIx = AddNewVideoClip();
mClips[lClipIx]->SetName ( lName );
mClips[lClipIx]->SetLoopCount ( lLoopCnt );
mClips[lClipIx]->SetLoopsLeft ( lLoopLeft );
if( lVideoIx != -1 )
{
mClips[lClipIx]->SetVideo( lVideoMedia[lVideoIx] );
}
}
pFbxObject->FieldReadEnd();
}
}
return true;
}
void ORDeviceVideo::VideoClipEndCallback(
HISender pSender,
HKEvent pEvent )
{
FBEventVideoSwitcher lEvent( pEvent );
int lNextIndex;
int lCurBase = mCurrentIndex;
int lCount;
lCount = mClips.GetCount();
if( mCurrentIndex >= (lCount-1) && GetLoopMode() )
{
lCurBase = -1;
}
lNextIndex = lCurBase + 1;
if( lCurBase < (lCount-1) )
{
ORVideoEntry* lCurClp = mClips[mCurrentIndex];
ORVideoEntry* lNxtClp = mClips[lNextIndex];
int lLoopsLeft = lCurClp->GetLoopsLeft();
if( lLoopsLeft > 0 )
{
lCurClp->SetLoopsLeft( --lLoopsLeft );
}
else
{
lCurClp->SetLoopsLeft( lCurClp->GetLoopCount() );
if( lNextIndex >= (lCount) )
{
lNextIndex = -1;
}
{
if( lCurBase == -1 )
{
mCurrentIndex = -1;
}
mCurrentIndex ++;
}
}
}
}
bool ORDeviceVideo::GetUsingSystemTime()
{
if( mVideoSwitcher )
{
return mVideoSwitcher->UsingSystemTime;
}
return true;
}
void ORDeviceVideo::SetUsingSystemTime( bool pState )
{
mVideoSwitcher->UsingSystemTime = pState;
}
ORPlaybackMode ORDeviceVideo::GetPlaybackMode()
{
return mModePlayback;
}
void ORDeviceVideo::SetPlaybackMode( ORPlaybackMode pMode )
{
mModePlayback = pMode;
switch( pMode )
{
case kORPlaybackFreeRunning: this->SetUsingSystemTime(true); break;
case kORPlaybackGlobalFrame: break;
case kORPlaybackLocalFrame: break;
}
}